package com.ytjj.qmyx.mall.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.gexin.fastjson.JSON;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.request.QueryTrackParam;
import com.kuaidi100.sdk.request.QueryTrackReq;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.kuaidi100.sdk.response.QueryTrackResp;
import com.kuaidi100.sdk.utils.PropertiesReader;
import com.kuaidi100.sdk.utils.SignUtils;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.api.ResultCode;
import com.ytjj.common.constants.*;
import com.ytjj.common.dto.mqdto.PrepaidRefillDto;
import com.ytjj.common.dto.mqdto.ProductStatisticsDto;
import com.ytjj.common.dto.mqdto.SellAfterDto;
import com.ytjj.common.dto.mqdto.SmsDto;
import com.ytjj.common.enums.PlatformEnum;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.exception.GlobalExceptionHandler;
import com.ytjj.common.model.UsersResponse;
import com.ytjj.common.model.YxAlipayConfig;
import com.ytjj.common.model.request.AliyunMallPVRequest;
import com.ytjj.common.model.request.AliyunMallRequest;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.*;
import com.ytjj.common.utils.feishu.FeiShuUtil;
import com.ytjj.qmyx.mall.client.FreightTemplateClient;
import com.ytjj.qmyx.mall.config.MyWxConfig;
import com.ytjj.qmyx.mall.config.SupplyApiConfig;
import com.ytjj.qmyx.mall.constants.ExpireTimeConstant;
import com.ytjj.qmyx.mall.constants.RedisConstants;
import com.ytjj.qmyx.mall.constants.*;
import com.ytjj.qmyx.mall.constants.WxPayTypeConstant;
import com.ytjj.qmyx.mall.enums.*;
import com.ytjj.qmyx.mall.mapper.*;
import com.ytjj.qmyx.mall.model.*;
import com.ytjj.qmyx.mall.model.dto.*;
import com.ytjj.qmyx.mall.model.request.*;
import com.ytjj.qmyx.mall.model.response.*;
import com.ytjj.qmyx.mall.service.*;
import com.ytjj.qmyx.mall.service.adapay.AdaPayService;
import com.ytjj.qmyx.mall.utils.*;
import com.ytjj.qmyx.users.client.UsersClient;
import com.ytjj.qmyx.users.mapper.UsersAddressMapper;
import com.ytjj.qmyx.users.mapper.UsersMapper;
import com.ytjj.qmyx.users.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 订单服务实现类
 *
 *
 * @version 1.0
 *
 */
@Slf4j
@Service
@RefreshScope
public class OrdersServiceImpl implements OrdersService {

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private OrdersPayMapper ordersPayMapper;

    @Resource
    private OrdersInfoMapper ordersInfoMapper;
    @Resource
    private SysConfigUtil sysConfigUtil;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;
    @Resource
    private OrderInfoDao orderInfoDao;

    private final ProductService productService;

    private final CommonService commonService;

    private final ActivityService activityService;

    private final UsersClient usersClient;

    private final RedisService redisService;

    @Resource
    private OrdersDao ordersDao;

    @Autowired
    private Map<String, CreateOrderService> createOrderService;

    @Autowired
    private Map<String, WxService> wxServiceMap;

    @Resource
    private OrdersRewardMapper ordersRewardMapper;

    @Resource
    private CouponRecordsDao couponRecordsDao;

    @Resource
    private PhoneRechargeConfigMapper phoneRechargeConfigMapper;
    @Resource
    private UsersMapper usersMapper;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private RedissonClient redissonClient;

    @Autowired
    private GroupActivityService groupActivityService;
    @Autowired
    private YxGroupBuyUserRelService yxGroupBuyUserRelService;
    @Autowired
    private YxProductGroupBuyInfoService yxProductGroupBuyInfoService;
    @Resource
    private ReturnGoodsMapper returnGoodsMapper;
    @Resource
    private EveryDayIncrementVarUtil everyDayIncrementVarUtil;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private ProductSpecMapper productSpecMapper;
    @Resource
    private AdaPayService adaPayService;
    @Resource
    private UsersGetuiInfoService usersGetuiInfoService;

    @Value("${order.push.switch:false}")
    private Boolean orderPushSwitch;//订单实时推送开关

    @Value("${brokerageRatio:1.6}")
    private String brokerageRatio;
    @Value("${subsidyDay:7}")
    private String subsidyDay;
    //是否计算运费 1-计算 0-不计算
    @Value("${yunfeiSwitch:1}")
    private String yunfeiSwitch;
    @Value("${paySucReturnUrl.channel:ssvip,kq,vip,kvip}")
    private String paySucReturnUrl;
    //服务商id
    @Value("${dealer_id:7E3N}")
    private String serviceId;

    @Value("${baiduToken:FnMsmoneZfIY1SS7AGekqFfYcq1LlIcu@I0rZjsLf9rRbosPGVorrB8ylDwBeFMFj}")
    private String baiduToken;

    @Value("${alipayZeroFlag:false}")
    private boolean alipayZeroFlag;

    @Value("${short.platfrom.url:}")
    private String shortUrl;
    @Value("${urlOld:}")
    private String urlOld;
    @Value("${urlNew:}")
    private String urlNew;

    /**
     * 报警间隔时间
     */
    @Value("${intervalTime:60}")
    private long intervalTime;

    /**
     * 未支付预警数量
     */
    @Value("${alipayUnpayCount:30}")
    private Integer alipayUnpayCount;

    @Resource
    private DynamicMapper dynamicMapper;
    @Resource
    private HelpWorkMapper helpWorkMapper;
    @Resource
    private UsersRealNameMapper usersRealNameMapper;
    @Resource
    private HelpWorkInfoDao helpWorkInfoDao;
    @Resource
    private SupplyApiConfig supplyApiConfig;
    @Resource
    private OrdersRefundMapper refundMapper;

    @Autowired
    private FreightTemplateClient freightTemplateClient;

    @Resource
    private UsersAddressMapper usersAddressMapper;
    @Resource
    private OrderDisparitiesRefundListMapper orderDisparitiesRefundListMapper;
    /**
     * 实时查询微信订单支付结果开关
     * 1-开启 0-关闭
     */
    @Value("${real.wxOrderQuery.switch:0}")
    private Integer realWxOrderQuerySwitch;
    @Value("${blacklist.tel:13683553325,15248360124,18873058010}")
    private String blackListTel;
    // 一个 token 一天限制下单数
    @Value("${h5.create_order.maxnum:100}")
    private Integer h5CreateOrderMaxNum;

    @Value("${order.region:吴江区}")
    private String regionAddress;

    //限制下单地址
    @Value("${order.blackAddress:公安局,派出所,检察院,法院,工商局}")
    private String blackAddress;

    @Resource
    private AdvertCallBackService advertCallBackService;
    @Resource
    private OrdersTransferLogMapper ordersTransferLogMapper;
    @Resource
    private OrdersTransferManageMapper ordersTransferManageMapper;
    @Resource
    private OrdersTransferLogDao ordersTransferLogDao;
    @Resource
    private SysConfigMapper sysConfigMapper;

    @Resource
    private PayConfigDao payConfigDao;

    //飞书预警下单数量
    @Value("${checkOrderNum:5}")
    private Integer checkOrderNum;

    /**
     * 支付宝被风控过的域名
     */
    @Value("${zfbBlackUrl:https://xz.iuz9.cn}")
    private String zfbBlackUrl;

    private static final String RECHARGE_LOCK = "RECHARGE_LOCK_";
    public static final String COMPANY = "guobao";

    BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(1024 * 1024);
    Executor pools = new ThreadPoolExecutor(5, 10, 5,
            TimeUnit.SECONDS, new LinkedBlockingQueue<>(1024 * 1024));

    @Override
    public void addTask(Integer orderId) {
        //添加一个元素并返回true  如果队列已满，则返回false
        queue.offer(orderId);
    }

    class UploadOrderTask implements Runnable {
        @Override
        public void run() {
            for (; ; ) {
                if (orderPushSwitch) {
                    try {
                        Integer orderId = queue.take();//如果队列为空 则阻塞
                        log.info("上传供应链3============{}", orderId);
                        ordersUpload(orderId,null);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    //    @PostConstruct // 现在没有使用就注释了  等待使用队列方式的时候 这个就需要放开
    public void startCosummer() {
        UploadOrderTask orderTask = new UploadOrderTask();
        new Thread(orderTask).start();
    }

    public OrdersServiceImpl(ProductService productService, ActivityService activityService, CommonService commonService, UsersClient usersClient, RedisService redisService) {
        this.productService = productService;
        this.activityService = activityService;
        this.commonService = commonService;
        this.usersClient = usersClient;
        this.redisService = redisService;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createOrder(CreateOrderRequest request) {
        //冻结库存前查一下库存是否足够用
        log.info("=============冻结库存前查一下库存是否足够用2=====================参数{},{}", request.getProductId(), request.getProductSpecId());
        String cacheKey = RedisKeyConstant.CACHE_CREATE_ORDER_TOKEN_KEY + TokenUtil.getToken();
        String cacheValueStr = redisService.get(cacheKey);
        if (!StringUtils.isEmpty(cacheValueStr)) {
            Long cacheValue = Long.valueOf(cacheValueStr);
            if (cacheValue > h5CreateOrderMaxNum) {
                throw new ApiException("下单失败,-100！");
            }
        }
        try {
            redisService.increment(cacheKey, 1);
            Date diffTime = getEndOfDay(new Date());
            Long diffTimeMils = diffTime.getTime() - System.currentTimeMillis();
            redisService.expire(cacheKey, diffTimeMils / 1000);
        } catch (Exception e) {
            redisService.expire(cacheKey, 3600);
        }
        boolean b = true;
        if (null == request.getProductId() && null == request.getProductSpecId() && StringUtils.isNotEmpty(request.getCartNoStr())) {
            b = true;
        } else {
            b = checkProductStock(request.getProductId(), request.getProductSpecId(), request.getProductSum());
        }
        if (!b) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
        }
        int orderId = createOrderService.get(request.getCreateType()).createOrder(request);

        try {
            //下单时冻结库存
            ProductStockFrozen(orderId);
        } catch (Exception e) {
            log.error("=========下单时冻结库存失败1======={}=={}", orderId, e);
        }
        return orderId;
    }

    /**
     * 减库存
     *
     * @param request
     */
    @Transactional(rollbackFor = Exception.class)
    public void subtractStock(CreateOrderRequest request) {
        Product productRequest = productMapper.selectByPrimaryKey(request.getProductId());
        ProductSpec productSpecRequest = productSpecMapper.selectByPrimaryKey(request.getProductSpecId());
        try {
            //减库存-------------------------------------------------------------2021-9-9
            // 减库存 //TODO--------目前每笔订单生成的数量只有一个
            log.info("================开始下单减库存==============={}");
            Integer sum = 1;
            if (productRequest.getIsZeroProduct() != null && productRequest.getIsZeroProduct() == 1 && productRequest.getStockEvaluation() != null && productRequest.getStockEvaluation() > 0) {
                productRequest.setStockEvaluation(productRequest.getStockEvaluation() - sum);
            } else {
                productRequest.setStock(Optional.ofNullable(productRequest.getStock()).orElse(0) - sum);
            }
            productMapper.updateByPrimaryKeySelective(productRequest);
            productSpecRequest.setBuySum(Optional.ofNullable(productSpecRequest.getBuySum()).orElse(0) + sum);
            productSpecRequest.setStock(Optional.ofNullable(productSpecRequest.getStock()).orElse(0) - sum);
            productSpecMapper.updateByPrimaryKeySelective(productSpecRequest);
        } catch (Exception e) {
            log.error("================下单减库存失败===目前每笔订单生成的商品数量只有一个==============={}", request.getProductSpecId());
        }
    }

    /**
     * 扣减库存
     *
     * @param productId
     * @param productSpecId
     */
    @Async
    public void subtractStock(Integer productId, Integer productSpecId) {
        log.info("================开始下单减库存==============={},{}", productId, productSpecId);
        Product productRequest = productMapper.selectByPrimaryKey(productId);
        ProductSpec productSpecRequest = productSpecMapper.selectByPrimaryKey(productSpecId);
        try {
            // 减库存 //TODO--------目前每笔订单生成的数量只有一个
            Integer sum = 1;
            if (productRequest.getIsZeroProduct() != null && productRequest.getIsZeroProduct() == 1 && productRequest.getStockEvaluation() != null && productRequest.getStockEvaluation() > 0) {
                productRequest.setStockEvaluation(productRequest.getStockEvaluation() - sum);
            } else {
                productRequest.setStock(Optional.ofNullable(productRequest.getStock()).orElse(0) - sum);
            }
            productMapper.updateByPrimaryKeySelective(productRequest);
            productSpecRequest.setBuySum(Optional.ofNullable(productSpecRequest.getBuySum()).orElse(0) + sum);
            productSpecRequest.setStock(Optional.ofNullable(productSpecRequest.getStock()).orElse(0) - sum);
            productSpecMapper.updateByPrimaryKeySelective(productSpecRequest);
        } catch (Exception e) {
            log.error("================下单减库存失败===目前每笔订单生成的商品数量只有一个==============={},{}", productId, productSpecId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer cartCreateOrder(CreateOrderRequest request) {
        log.info("===cartCreateOrder request==={}", request.toString());
        Integer result = createOrderService.get(request.getCreateType()).cartCreateOrder(request);
        //todo 记录订单规格信息
        return result;
    }

    /**
     * 验证该订单号是否存在
     *
     * @param
     * @return
     */
    public String checkOrderNo() {
        String newOrderCode = OrderUtils.getNewOrderCode();
        Integer count = ordersDao.selectByOrderNo(newOrderCode);
        if (count > 0) {
            newOrderCode = checkOrderNo();
        }
        return newOrderCode;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Orders saveOrders(Integer userId, String tel, BigDecimal originalPrice, BigDecimal price, String orderSource, String channel, Integer isHelpOrder) {

        Orders orders = new Orders();
        String newOrderNo = checkOrderNo();
        orders.setOrderNo(newOrderNo);
        orders.setUserId(userId);
        orders.setTel(tel);
        orders.setGoodsMoney(originalPrice);
        orders.setDeliverType(DeliverTypeEnums.delivery.name());
        orders.setTotalMoney(originalPrice);
        orders.setRealTotalMoney(price);
        orders.setIsPay(IsPayConstant.NO);
        orders.setChannel(TokenUtil.getChannel());
        orders.setH5Token(TokenUtil.getUuid());
        orders.setOrderSource(orderSource);
        // 是否首次创建订单
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andUserIdEqualTo(userId);
        long count = ordersMapper.countByExample(ordersExample);
        orders.setIsFirstBuy(count == 0 ? 1 : null);
        orders.setCreateTime(new Date());

        DefaultAddressDto defaultAddressDto = usersClient.getDefaultAddress(userId);
        if (defaultAddressDto == null) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ADDRESS_NONEXISTENT));
        }
        orders.setProvince(defaultAddressDto.getProvince());
        orders.setCity(defaultAddressDto.getCity());
        orders.setArea(defaultAddressDto.getArea());
        orders.setAddress(defaultAddressDto.getAddress());
        if (StringUtils.isNotBlank(defaultAddressDto.getProvince()) &&
                StringUtils.isNotBlank(defaultAddressDto.getCity()) &&
                StringUtils.isNotBlank(defaultAddressDto.getArea())) {
            orders.setUserAddress(defaultAddressDto.getProvince() + defaultAddressDto.getCity() + defaultAddressDto.getArea() + defaultAddressDto.getAddress());
        }
        orders.setUserName(defaultAddressDto.getName());
        orders.setUserPhone(defaultAddressDto.getTel());
        orders.setOrderStatus(OrderStatusEnums.OBLIGATION.getValue());

        if (isHelpOrder == 1) {
            orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
            orders.setPayTime(new Date());
            orders.setPaySource("evaluation");
            orders.setTotalMoney(BigDecimal.ZERO);
            orders.setRealTotalMoney(BigDecimal.ZERO);
        }
        if (isHelpOrder == 2) {
            orders.setOrderStatus(OrderStatusEnums.OBLIGATION.getValue());
            orders.setPayTime(new Date());
            orders.setPaySource("evaluation");
        }
        ordersMapper.insertSelective(orders);
        return orders;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Orders saveOrders(Integer userId, String tel, BigDecimal originalPrice, BigDecimal price, String orderSource, String channel, Integer isHelpOrder, String orderParentNo) {

        Orders orders = new Orders();
        try {
            String orderNo = OrderUtils.generateOrderNo() + everyDayIncrementVarUtil.increByEveryDay() + OrderUtils.generateRandom();
            log.info("===new orderNo==={}", orderNo);
        } catch (Exception e) {
        }
        String newOrderNo = checkOrderNo();
        orders.setOrderNo(newOrderNo);
        orders.setUserId(userId);
        orders.setTel(tel);
        orders.setGoodsMoney(originalPrice);
        orders.setDeliverType(DeliverTypeEnums.delivery.name());
        orders.setTotalMoney(originalPrice);
        orders.setRealTotalMoney(price);
        orders.setIsPay(IsPayConstant.NO);
        orders.setChannel(TokenUtil.getChannel());
        orders.setH5Token(TokenUtil.getUuid());
        orders.setOrderSource(orderSource);
        // 是否首次创建订单
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andUserIdEqualTo(userId);
        long count = ordersMapper.countByExample(ordersExample);
        orders.setIsFirstBuy(count == 0 ? 1 : null);
        orders.setCreateTime(new Date());

        DefaultAddressDto defaultAddressDto = usersClient.getDefaultAddress(userId);
        if (defaultAddressDto == null) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ADDRESS_NONEXISTENT));
        }
        orders.setProvince(defaultAddressDto.getProvince());
        orders.setCity(defaultAddressDto.getCity());
        orders.setArea(defaultAddressDto.getArea());
        orders.setAddress(defaultAddressDto.getAddress());
        if (StringUtils.isNotBlank(defaultAddressDto.getProvince()) &&
                StringUtils.isNotBlank(defaultAddressDto.getCity()) &&
                StringUtils.isNotBlank(defaultAddressDto.getArea())) {
            orders.setUserAddress(defaultAddressDto.getProvince() + defaultAddressDto.getCity() + defaultAddressDto.getArea() + defaultAddressDto.getAddress());
        }
        orders.setUserName(defaultAddressDto.getName());
        orders.setUserPhone(defaultAddressDto.getTel());
        orders.setOrderStatus(OrderStatusEnums.OBLIGATION.getValue());

        if (isHelpOrder == 1) {
            orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
            orders.setPayTime(new Date());
            orders.setPaySource("evaluation");
            orders.setTotalMoney(BigDecimal.ZERO);
            orders.setRealTotalMoney(BigDecimal.ZERO);
        }
        orders.setOrderParentNo(orderParentNo);
        if (StringUtils.isNotEmpty(blackListTel)) {
            List blackList = Arrays.asList(blackListTel.split(","));
            if (blackList.contains(orders.getTel()) || blackList.contains(orders.getUserPhone())) {
                throw new ApiException("该地区不可下单,请更改默认地址！");
            }
        }
        ordersMapper.insertSelective(orders);
        return orders;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Orders saveOrders(Integer userId, String tel, BigDecimal originalPrice, BigDecimal price, String orderSource,
                             String channel, BigDecimal deduction, Integer dynamicId, String orderParentNo,String account) {

        Orders orders = new Orders();
        String newOrderNo = checkOrderNo();
        orders.setOrderNo(newOrderNo);
        orders.setUserId(userId);
        orders.setTel(tel);
        orders.setGoodsMoney(originalPrice);
        orders.setDeliverType(DeliverTypeEnums.delivery.name());
        orders.setTotalMoney(originalPrice);
        orders.setRealTotalMoney(price);
        orders.setIsPay(IsPayConstant.NO);
        orders.setChannel(TokenUtil.getChannel());
        orders.setH5Token(TokenUtil.getToken());
        orders.setOrderSource(orderSource);
        orders.setDeductionMoney(deduction);
        // 是否首次创建订单
        if (userId!=null){
            OrdersExample ordersExample = new OrdersExample();
            ordersExample.createCriteria().andUserIdEqualTo(userId);
            long count = ordersMapper.countByExample(ordersExample);
            orders.setIsFirstBuy(count == 0 ? 1 : null);
        }
        orders.setCreateTime(new Date());
        orders.setDynamicId(dynamicId);

        DefaultAddressDto defaultAddressDto = usersClient.getDefaultAddress(userId);
        if (StringUtils.isNotBlank(TokenUtil.getSourcePlatform()) && "zfb".equals(TokenUtil.getSourcePlatform())) {
            log.info("用户userId= :{}下单默认用户地址:{}",userId,JSONObject.toJSONString(defaultAddressDto));
        }
        if (null != defaultAddressDto) {
            orders.setProvince(defaultAddressDto.getProvince());
            orders.setCity(defaultAddressDto.getCity());
            orders.setArea(defaultAddressDto.getArea());
            orders.setAddress(defaultAddressDto.getAddress());
            if (StringUtils.isNotBlank(defaultAddressDto.getProvince()) &&
                    StringUtils.isNotBlank(defaultAddressDto.getCity()) &&
                    StringUtils.isNotBlank(defaultAddressDto.getArea())) {
                orders.setUserAddress(defaultAddressDto.getProvince() + defaultAddressDto.getCity() + defaultAddressDto.getArea() + defaultAddressDto.getAddress());
            }
            orders.setUserName(defaultAddressDto.getName());
            orders.setUserPhone(defaultAddressDto.getTel());
        }
        orders.setOrderStatus(OrderStatusEnums.OBLIGATION.getValue());
        orders.setOrderParentNo(orderParentNo);
        if (StringUtils.isNotEmpty(blackListTel)) {
            List blackList = Arrays.asList(blackListTel.split(","));
            if (blackList.contains(orders.getTel()) || blackList.contains(orders.getUserPhone())) {
                throw new ApiException("该地区不可下单,请更改默认地址！");
            }
        }
        //敏感地址限制
//        if (org.apache.commons.lang3.StringUtils.isNotBlank(orders.getAddress()) && blackAddress!=null){
//            String[] blackAddressList = blackAddress.split(",");
//            for (String bd : blackAddressList) {
//                if (orders.getAddress().contains(bd)){
//                    throw new ApiException("该地区不可下单,-3");
//                }
//            }
//        }
        //推广账号
        if (StringUtils.isNotBlank(account)){
            orders.setAccount(account);
        }
        ordersMapper.insertSelective(orders);
        return orders;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Orders saveOrders(Integer userId, String tel, String province, String city, String area, String address,
                             String userName, BigDecimal originalPrice, BigDecimal price, String orderSource,
                             String channel, String h5token, String orderParentNo,String domainUrl,String orderPlatform,BigDecimal deductionMoney) {
        Orders orders = new Orders();

        String newOrderNo = checkOrderNo();
        orders.setOrderNo(newOrderNo);
        orders.setUserId(userId);
        orders.setTel(tel);
        orders.setProvince(province);
        orders.setCity(city);
        orders.setArea(area);
        orders.setAddress(address);
        if (StringUtils.isNotBlank(province) && StringUtils.isNotBlank(city)) {
            orders.setUserAddress(province + city + (StringUtils.isEmpty(area) ? "" : area) + address);
        }
        if (StringUtils.isEmpty(orders.getUserAddress())) {
            orders.setUserAddress(address);
        }
        orders.setUserPhone(tel);
        orders.setUserName(userName);
        orders.setOrderStatus(OrderStatusEnums.OBLIGATION.getValue());
        orders.setGoodsMoney(originalPrice);
        orders.setDeliverType(DeliverTypeEnums.delivery.name());
        orders.setTotalMoney(originalPrice);
        orders.setRealTotalMoney(price);
        orders.setIsPay(IsPayConstant.NO);
        orders.setOrderSource(orderSource);
        orders.setChannel(orderSource.equals("ios") || orderSource.equals("weapp") ? orderSource : channel);
        orders.setCreateTime(new Date());
        orders.setH5Token(h5token);
        orders.setOrderParentNo(orderParentNo);
        orders.setDomainUrl(domainUrl);
        // 是否首次创建订单
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andH5TokenEqualTo(h5token);
        long count = ordersMapper.countByExample(ordersExample);
        if (count <= 0) {
            orders.setIsFirstBuy(1);
        }
        orders.setOrderPlatform(orderPlatform);
        orders.setDeductionMoney(deductionMoney);
        ordersMapper.insertSelective(orders);
        return orders;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrdersInfo saveOrdersInfo(Integer orderId, Integer productId, String productName, String productImg,
                                     BigDecimal price, BigDecimal originalPrice, String warehouse,
                                     String warehouseName, String warehouseRule, Integer specialId,
                                     String skuSpec, Integer bankerId, Integer specId, String activityType,
                                     Integer activityId, BigDecimal activityMax, BigDecimal activityMin, String descr,
                                     Integer isDirectBuy, String pageSource, Integer evaluationId, Integer productType,
                                     Integer isHelpOrder, BigDecimal costPrice, Integer productSum, String two) {
        return saveOrdersInfo(orderId, productId, productName, productImg,
                price, originalPrice, warehouse,
                warehouseName, warehouseRule, specialId,
                skuSpec, bankerId, specId, activityType,
                activityId, activityMax, activityMin, descr,
                isDirectBuy, pageSource, evaluationId, productType, isHelpOrder, costPrice, productSum);
    }

    /**
     * 根据订单id查询
     *
     * @param orderId
     * @return
     */
    public String getOrderSource(Integer orderId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        return orders.getOrderSource();
    }

    /**
     * 获取子订单号
     *
     * @return
     */
    public String getChildOrderNo(String orderSource) {
        String childOrderNo = OrderUtils.getChildOrderNo(orderSource);
        Integer count = ordersDao.selectByChildOrderNo(childOrderNo);
        if (count > 0) {
            childOrderNo = getChildOrderNo(orderSource);
        }
        return childOrderNo;
    }

    @Override
    public OrdersInfo saveOrdersInfo(Integer orderId, Integer productId, String productName, String productImg, BigDecimal price, BigDecimal originalPrice, String warehouse, String warehouseName, String warehouseRule, Integer specialId, String skuSpec, Integer bankerId, Integer specId, String activityType, Integer activityId, BigDecimal activityMax, BigDecimal activityMin, String descr, Integer isDirectBuy, String pageSource, Integer evaluationId, Integer productType, Integer isHelpOrder, BigDecimal costPrice, Integer productSum) {
        OrdersInfo ordersInfo = new OrdersInfo();
        String orderSource = getOrderSource(orderId);
        ordersInfo.setChildOrderNo(getChildOrderNo(orderSource));
        ordersInfo.setOrderId(orderId);
        ordersInfo.setProductId(productId);
        ordersInfo.setEvaluationId(evaluationId);
        ordersInfo.setProductName(productName);
        ordersInfo.setProductImg(productImg);
        ordersInfo.setProductPrice(price);
        ordersInfo.setProductOprice(originalPrice);
        ordersInfo.setProductSum(productSum);
        ordersInfo.setWarehouse(warehouse);
        ordersInfo.setWarehouseName(warehouseName);
        ordersInfo.setWarehouseRule(warehouseRule);
        ordersInfo.setSpecialId(specialId);
        ordersInfo.setProductSkuSpec(skuSpec);
        ordersInfo.setBankerId(bankerId);
        ordersInfo.setCreateTime(new Date());
        ordersInfo.setProductSpecId(specId);
        ordersInfo.setActivityType(activityType);
        ordersInfo.setActivityId(activityId);
        ordersInfo.setActivityMax(activityMax);
        ordersInfo.setActivityMin(activityMin);
        ordersInfo.setDescr(descr);
        ordersInfo.setFakeExpress(FakeExpressUtil.getFakeExpress().toJSONString());
        ordersInfo.setIsDirectbuy(isDirectBuy);
        ordersInfo.setPageSource(pageSource);
        ordersInfo.setIsWalletPay(0);
        ordersInfo.setProductType(String.valueOf(null == productType ? "" : productType));
        ordersInfo.setIsHelpOrder(isHelpOrder);
        ordersInfo.setCostPrice(costPrice);

//        //计算并保存运费信息
//        try {
//            log.info("==========开始计算并保存运费信息==============={},{}", productId, ordersInfo.getChildOrderNo());
//            saveOrderInfoFreight(orderId, productId, ordersInfo);
//        } catch (Exception e) {
//            log.error("=====计算运费异常====={},{}", orderId, e);
//        }
        saveOrderInfoFreight(orderId, productId, ordersInfo);


        // 记录假快递信息
        ordersInfo.setFakeExpress(FakeExpressUtil.getFakeExpress().toJSONString());
        if (isHelpOrder == 1) {
            // 助力订单状态为待发货
            ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
        } else {
            ordersInfo.setOrderinfoStatus(OrderStatusEnums.OBLIGATION.getValue());
        }
        ordersInfoMapper.insertSelective(ordersInfo);
        return ordersInfo;
    }

    public void saveOrderInfoFreight(Integer orderId, Integer productId, OrdersInfo ordersInfo) {
        //计算运费
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);

        BigDecimal freight = BigDecimal.ZERO;
        createOrderInfoFreight(ordersInfo, orders, freight, null);


        //是否需要算运费 1-算 其它不算
//        if ("1".equals(yunfeiSwitch)) {
//
//            //用供应商运费模板
//            FreightTemplateResponse freightTemplateResponse = getFreightTemplateResponse(productId);
//            freight = calculateFreight(freightTemplateResponse, ordersInfo.getProductSum(), orders.getCity(), orders.getProvince(), null);
//
//
//            createOrderInfoFreight(ordersInfo, orders, freight, null != ownerTemplate ? ownerTemplate.getId() : null);
//        } else {
//            createOrderInfoFreight(ordersInfo, orders, freight, null);
//        }
    }

    public void createOrderInfoFreight(OrdersInfo ordersInfo, Orders orders, BigDecimal freight, Integer freightId) {
        //保存运费信息
        OrdersInfoFreightDto ordersInfoFreightDto = new OrdersInfoFreightDto();
        ordersInfoFreightDto.setFreight(freight);
        ordersInfoFreightDto.setChildOrderNo(ordersInfo.getChildOrderNo());
        ordersInfoFreightDto.setProductId(ordersInfo.getProductId());
        ordersInfoFreightDto.setCreateTime(new Date());
        ordersInfoFreightDto.setFreightId(freightId);
        ordersDao.insertOrdersInfoFreight(ordersInfoFreightDto);

        //把运费添加到付款金额中
        orders.setRealTotalMoney(orders.getRealTotalMoney().add(freight));
        orders.setTotalMoney(orders.getTotalMoney().add(freight));
        ordersMapper.updateByPrimaryKeySelective(orders);
    }

    /**
     * 计算运费
     *
     * @param
     * @param productNum
     * @param city
     * @return
     */
    @Override
    public BigDecimal calculateFreight(FreightTemplateResponse freightTemplateResponse, Integer productNum, String city,String province) {

        AtomicReference<BigDecimal> freight = new AtomicReference<>(new BigDecimal(0));

        if ("市辖区".equals(city)){
            city = province;
        }

//        log.info("==========计算运费的参数============freightTemplateResponse{},city{}", freightTemplateResponse, city);
        //判断是否在限制地区
//        YxAstrictRegionResponse astrictRegion = freightTemplateResponse.getAstrictRegion();
//        if (null != astrictRegion && StringUtils.isNotBlank(astrictRegion.getRegion())) {
//            String[] region = astrictRegion.getRegion().split(",");
//            String finalCity = city;
//            Optional<String> regionFlag = Stream.of(region).filter(x -> x.equals(finalCity)).findFirst();
//            if (regionFlag.isPresent()) {
//                if (StringUtils.isNotBlank(regionFlag.get())) {
//                    throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
//                }
//            }
//        }
        //判断是否在限制地区
        Boolean judgeResult = judgeRegionList(freightTemplateResponse, city);
        if(!judgeResult) {
            throw new ApiException("该地区不可下单,请更改默认地址");
        }


//        log.info("========查询到的运费模板========freightTemplateResponse:{},city:{}", freightTemplateResponse, city);
        if (null != freightTemplateResponse && freightTemplateResponse.getFreightWay() != null) {
            if (freightTemplateResponse.getFreightWay() == 0) {
                List<YxAssignFreightResponse> assignFreightList = freightTemplateResponse.getAssignFreightList();
                AtomicReference<Boolean> flag = new AtomicReference<>(false);//记录是否符合自定义模板地区
                if (!flag.get()) {
                    String finalCity1 = city;
                    assignFreightList.stream().filter(assignFreight -> StringUtils.isNotEmpty(assignFreight.getRegion())).forEach(assignFreight -> {
                        String[] split = assignFreight.getRegion().split(",");
                        Optional<String> cityfrist = Stream.of(split).filter(x -> x.equals(finalCity1)).findFirst();
                        String[] provinceSplit = assignFreight.getRegionDesc().split(",");
                        Optional<String> provincefrist = Stream.of(provinceSplit).filter(x -> x.contains("[全境]") && province.equals(x.replace("[全境]",""))).findFirst();
                        //指定地区为全境或者指定城市，均按照指定运费计算
                        if ((cityfrist.isPresent() && StringUtils.isNotBlank(cityfrist.get()))
                                || (provincefrist.isPresent() && StringUtils.isNotBlank(provincefrist.get()))) {
                            if (productNum <= assignFreight.getAmount()) {
                                freight.set(assignFreight.getFreight());//如果只有一件商品,订单运费 = 模板运费
                                flag.set(true);
                            } else {
                                float num = productNum - assignFreight.getAmount();
                                int continues = assignFreight.getContinues();
                                int renewNum = (int) Math.ceil(num / continues);

                                freight.set(assignFreight.getFreight()
                                        .add(assignFreight.getRenew()
                                                .multiply(new BigDecimal(renewNum))));  //如果有多件,订单运费=模板运费+续件数*续件运费
                                flag.set(true);
                            }
                        }
                    });
                }
                if (!flag.get()) {
                    if (productNum <= freightTemplateResponse.getAmount()) {
                        freight.set(freightTemplateResponse.getFreight());//如果只有一件商品,订单运费 = 模板运费
                    } else {
                        float num = productNum - freightTemplateResponse.getAmount();
                        int continues = freightTemplateResponse.getContinues();
                        int renewNum = (int)Math.ceil(num/continues);

                        freight.set(freightTemplateResponse.getFreight()
                                .add(freightTemplateResponse.getRenew()
                                        .multiply(new BigDecimal(renewNum))));  //如果有多件,订单运费=模板运费+续件数*续件运费
                    }
                }
            } else if (freightTemplateResponse.getFreightWay() == 1) {
                freight.set(freightTemplateResponse.getFreight().multiply(new BigDecimal(productNum)));//如果只有一件商品,订单运费 = 模板运费
            } else {
                freight.set(new BigDecimal(0));
            }
        }
        return freight.get();
    }


    private  Boolean judgeRegionList(FreightTemplateResponse freightTemplateResponse,String city){
        List<String> regionList = Lists.newArrayList();
        if(freightTemplateResponse != null) {
            YxAstrictRegionResponse astrictRegion = freightTemplateResponse.getAstrictRegion();
            if (null != astrictRegion && StringUtils.isNotBlank(astrictRegion.getRegion())) {
                List<String> regions = Arrays.asList(astrictRegion.getRegion().split(","));
                regionList.addAll(regions);
            }
        }
        if(!CollectionUtils.isEmpty(regionList)) {
            if( regionList.contains(city)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public BigDecimal getCalculateFreight(Integer orderId, String city,String province) {
        //是否需要算运费 1-算 其它不算
        if (!"1".equals(yunfeiSwitch)) {
            return BigDecimal.ZERO;
        }
        List<OrdersInfo> list = ordersDao.findProductCount(orderId);
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        BigDecimal totalFreight = new BigDecimal(0);
        for (OrdersInfo info : list) {
            //获取运费模板
            FreightTemplateResponse freightTemplateResponse = getFreightTemplateResponse(info.getProductId());

            if (null != freightTemplateResponse) {
                BigDecimal freight = this.calculateFreight(freightTemplateResponse,info.getProductSum(), city,province);
                totalFreight = totalFreight.add(freight);
                //查询运费数据是否存在
                OrdersInfoFreightDto dto = ordersDao.selectFreightByChildOrderNo(info.getChildOrderNo());
                if (null != dto) {
                    //更新子订单运费
                    ordersDao.updateFreight(freight, info.getChildOrderNo());
                    //更新主订单支付金额
                    orders.setTotalMoney(orders.getTotalMoney().subtract(dto.getFreight()).add(freight));
                    orders.setRealTotalMoney(orders.getRealTotalMoney().subtract(dto.getFreight()).add(freight));
                    ordersMapper.updateByPrimaryKeySelective(orders);
                } else {
                    //新增运费数据
                    createOrderInfoFreight(info, orders, freight, freightTemplateResponse.getId());
                }
            }
        }
        return totalFreight;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrdersInfo saveOrdersInfo(Integer orderId, Integer productId, String productName, String productImg,
                                     BigDecimal price, BigDecimal originalPrice, String warehouse,
                                     String warehouseName, String warehouseRule, Integer specialId,
                                     String skuSpec, Integer bankerId, Integer specId, String activityType,
                                     Integer activityId, BigDecimal activityMax, BigDecimal activityMin, String descr,
                                     Integer isDirectBuy, String pageSource, Integer evaluationId, Integer productType,
                                     Integer isHelpOrder, BigDecimal costPrice, String threeSkuId, Integer productSum, String typeOne,String scene) {
        OrdersInfo ordersInfo = new OrdersInfo();
        String orderSource = getOrderSource(orderId);
        ordersInfo.setChildOrderNo(getChildOrderNo(orderSource));
        ordersInfo.setOrderId(orderId);
        ordersInfo.setProductId(productId);
        ordersInfo.setEvaluationId(evaluationId);
        ordersInfo.setProductName(productName);
        ordersInfo.setProductImg(productImg);
        ordersInfo.setProductPrice(price);
        ordersInfo.setProductOprice(originalPrice);
        if (null == productSum) {
            productSum = 1;
        }
        ordersInfo.setProductSum(productSum);
        ordersInfo.setWarehouse(warehouse);
        ordersInfo.setWarehouseName(warehouseName);
        ordersInfo.setWarehouseRule(warehouseRule);
        ordersInfo.setSpecialId(specialId);
        ordersInfo.setProductSkuSpec(skuSpec);
        ordersInfo.setBankerId(bankerId);
        ordersInfo.setCreateTime(new Date());
        ordersInfo.setProductSpecId(specId);
        ordersInfo.setActivityType(activityType);
        ordersInfo.setActivityId(activityId);
        ordersInfo.setActivityMax(activityMax);
        ordersInfo.setActivityMin(activityMin);
        ordersInfo.setDescr(descr);
        ordersInfo.setFakeExpress(FakeExpressUtil.getFakeExpress().toJSONString());
        ordersInfo.setIsDirectbuy(isDirectBuy);
        ordersInfo.setPageSource(pageSource);
        ordersInfo.setIsWalletPay(0);
        ordersInfo.setProductType(String.valueOf(null == productType ? "" : productType));
        ordersInfo.setIsHelpOrder(isHelpOrder);
        ordersInfo.setCostPrice(costPrice);
        ordersInfo.setScene(scene);
        // 记录假快递信息
        ordersInfo.setFakeExpress(FakeExpressUtil.getFakeExpress().toJSONString());
        if (isHelpOrder == 1) {
            // 助力订单状态为待发货
            ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
        } else {
            ordersInfo.setOrderinfoStatus(OrderStatusEnums.OBLIGATION.getValue());
        }
        saveOrderInfoFreight(orderId, productId, ordersInfo);

        ordersInfo.setThreeSkuId(threeSkuId);
        ordersInfoMapper.insertSelective(ordersInfo);
        return ordersInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrdersInfo saveOrdersInfo(Integer orderId, Integer productId, String productName, String productImg,
                                     BigDecimal price, BigDecimal originalPrice, String warehouse,
                                     String warehouseName, String warehouseRule, Integer specialId,
                                     String skuSpec, Integer bankerId, Integer specId, String activityType,
                                     Integer activityId, BigDecimal activityMax, BigDecimal activityMin, String descr,
                                     Integer isDirectBuy, String pageSource, Integer evaluationId, Integer productType,
                                     Integer isHelpOrder, BigDecimal costPrice, String threeSkuId, Integer AppraisalType) {
        OrdersInfo ordersInfo = new OrdersInfo();
        String orderSource = getOrderSource(orderId);
        ordersInfo.setChildOrderNo(getChildOrderNo(orderSource));
        ordersInfo.setOrderId(orderId);
        ordersInfo.setProductId(productId);
        ordersInfo.setEvaluationId(evaluationId);
        ordersInfo.setProductName(productName);
        ordersInfo.setProductImg(productImg);
        ordersInfo.setProductPrice(price);
        ordersInfo.setProductOprice(originalPrice);
        ordersInfo.setProductSum(1);
        ordersInfo.setWarehouse(warehouse);
        ordersInfo.setWarehouseName(warehouseName);
        ordersInfo.setWarehouseRule(warehouseRule);
        ordersInfo.setSpecialId(specialId);
        ordersInfo.setProductSkuSpec(skuSpec);
        ordersInfo.setBankerId(bankerId);
        ordersInfo.setCreateTime(new Date());
        ordersInfo.setProductSpecId(specId);
        ordersInfo.setActivityType(activityType);
        ordersInfo.setActivityId(activityId);
        ordersInfo.setActivityMax(activityMax);
        ordersInfo.setActivityMin(activityMin);
        ordersInfo.setDescr(descr);
        ordersInfo.setFakeExpress(FakeExpressUtil.getFakeExpress().toJSONString());
        ordersInfo.setIsDirectbuy(isDirectBuy);
        ordersInfo.setPageSource(pageSource);
        ordersInfo.setIsWalletPay(0);
        ordersInfo.setProductType(String.valueOf(null == productType ? "" : productType));
        ordersInfo.setIsHelpOrder(isHelpOrder);
        ordersInfo.setCostPrice(costPrice);
        ordersInfo.setAppraisalType(AppraisalType);
        // 记录假快递信息
        ordersInfo.setFakeExpress(FakeExpressUtil.getFakeExpress().toJSONString());
        if (isHelpOrder == 1) {
            // 助力订单状态为待发货
            ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
        } else {
            ordersInfo.setOrderinfoStatus(OrderStatusEnums.OBLIGATION.getValue());
        }
        if (ordersInfo.getActivityType().equals(ActivityTypeEnums.ZERO_EVALUATION)) {
            String productStr = redisService.get("product:info:" + productId);
            Product product = (Product) JSONObject.parse(productStr);
            if (null != product) {
                ordersInfo.setAppraisalType(null == product.getAppraisalType() ? 1 : product.getAppraisalType());
            }
        }
        //计算并保存运费信息
        saveOrderInfoFreight(orderId, productId, ordersInfo);
//        //todo 测试已注释
//        try {
//            saveOrderInfoFreight(orderId, productId, ordersInfo);
//        } catch (Exception e) {
//            log.error("=====计算运费异常====={},{}", orderId, e);
//        }
        ordersInfo.setThreeSkuId(threeSkuId);
        ordersInfoMapper.insertSelective(ordersInfo);
        return ordersInfo;
    }

    @Override
//    @GlobalTransactional(timeoutMills = 300000)
    public Map balancePayByOrder(UnifiedOrderRequest request) {
        return wxDoUnifiedOrder(request);
    }

    @Override
    @Transactional
    public Map wxDoUnifiedOrder(UnifiedOrderRequest request) {
        log.info("===计算订单金额===3");
        Orders orders = ordersMapper.selectByPrimaryKey(request.getOrderId());
        if (IsPayConstant.YES.equals(orders.getIsPay())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PAID));
        }
        DefaultAddressDto address = usersClient.getOneAddress(orders.getUserId(), request.getAddressId());
        if (address == null) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ADDRESS_NONEXISTENT));
        }
        // 取出所有子订单
        List<OrdersInfo> ordersInfoList = ordersDao.getOrdersInfoList(request.getOrderId());
        // 取出第一条子订单
        OrdersInfo ordersInfo = ordersInfoList.get(0);

        // 检查是否存在支付订单号，如果存在，主动去微信查询订单结果
        if (StringUtils.isNotBlank(orders.getTradeNo())) {
            try {
                OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(orders.getTradeNo());
                Map<String, String> map = wxServiceMap.get("APP-" + pay.getTradeType()).wxOrderQuery(orders.getTradeNo());
                log.info("订单查询结果：{}", JSONObject.toJSONString(map));
                if ("SUCCESS".equals(map.get("trade_state"))) {
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
                } else if ("USERPAYING".equals(map.get("trade_state"))) {
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
                }
            } catch (Exception e) {
                e.printStackTrace();
                FeiShuUtil.sendMsg(String.format("wxDoUnifiedOrder接口调用微信下单查询失败,%s",e.getMessage()));
            }
        }

        // 获取订单号
        String resOrderNo = OrderUtils.getPayOrderCode(orders.getUserId());
        // 发起微信支付
        Map map;
        try {
            String productName = ordersInfo.getProductName().trim();
            if (productName.length()>15){
                productName = productName.substring(0,10);
            }
            WxPayDto wxPayDto = WxPayDto.builder()
                    .body(productName.trim())
                    .resOrderNo(resOrderNo)
                    .realTotalMoney(String.valueOf(Integer.valueOf(orders.getRealTotalMoney()
                            .multiply(new BigDecimal(100))
                            .setScale(0)
                            .intValue())))
                    .openid(request.getOpenid())
                    .productId(ordersInfo.getProductId())
                    .build();
            log.info("调取微信支付：req: {}", JSONObject.toJSONString(wxPayDto));
            map = wxServiceMap.get("APP-" + request.getType()).doUnifiedOrder(wxPayDto);
            log.info("调取微信支付结果：res: {}", JSONObject.toJSONString(map));
        } catch (Exception e) {
            log.error("==========》调微信失败e :{}", GlobalExceptionHandler.getExceptionToString(e));
            FeiShuUtil.sendMsg(String.format("wxDoUnifiedOrder接口调用微信下单接口失败,%s",e.getMessage()));
            throw new ApiException(e);
        }
        OrdersPay pay = new OrdersPay();
        pay.setAmount(orders.getRealTotalMoney());
        pay.setOrderNo(orders.getOrderNo());
        pay.setResOrderNo(resOrderNo);
        pay.setPayType(PayPayTypeEnums.BEING_PROCESSED.getType());
        pay.setTradeType(request.getType());
        pay.setCreateTime(new Date());
        try {
            pay.setPayConfigId(Integer.parseInt(map.get("payConfigId").toString()));
            log.info("===pay==={}", pay.toString());
        } catch (Exception e) {
            log.error("===获取支付时的配置id异常==={}", e);
        }
        ordersPayMapper.insertSelective(pay);
        orders.setProvince(address.getProvince());
        orders.setCity(address.getCity());
        orders.setAddress(address.getAddress());
        orders.setArea(address.getArea());
        orders.setUserAddress(address.getProvince() + address.getCity() + address.getArea() + address.getAddress());
        orders.setUserName(address.getName());
        orders.setUserPhone(address.getTel());
        orders.setOrderRemarks(request.getDesc());
        orders.setTradeNo(pay.getResOrderNo());
        orders.setIsAnonymity(request.getIsAnonymity());
        orders.setRealNameId(request.getRealNameId());
        ordersMapper.updateByPrimaryKeySelective(orders);
        return map;
    }

    @Override
    public Map wxDoUnifiedOrderV2(UnifiedOrderRequest request) {
        Orders orders = ordersDao.queryOrdersByOrderNo(request.getOrderNo());
        if (IsPayConstant.YES.equals(orders.getIsPay())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PAID));
        }
        if (StringUtils.isBlank(orders.getUserAddress())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ADDRESS_NONEXISTENT));
        }
        String city = orders.getCity();
        if (city.equals("市辖区")){
            city = orders.getProvince();
        }
        String province = orders.getProvince();

        //敏感地址限制
        if (org.apache.commons.lang3.StringUtils.isNotBlank(orders.getAddress()) && blackAddress!=null){
            String[] blackAddressList = blackAddress.split(",");
            for (String bd : blackAddressList) {
                if (orders.getAddress().contains(bd)){
                    throw new ApiException("该地区不可下单,-3");
                }
            }
        }

        //校验商品上下架/库存/收货地址
        if (null != request.getOrderId()){
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(request.getOrderId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            String finalCity = city;
            log.info("==========finalCity========{}",finalCity);

            ordersInfoList.stream().forEach(ordersInfo -> {
                boolean b = this.checkProductStock(ordersInfo.getProductId(), ordersInfo.getProductSpecId(), ordersInfo.getProductSum());
                if (!b){
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
                }
                //获取运费模板
                FreightTemplateResponse freightTemplateResponse = this.getFreightTemplateResponse(ordersInfo.getProductId());
                if (null != freightTemplateResponse) {
                    //判断是否在限制地区
                    YxAstrictRegionResponse astrictRegion = freightTemplateResponse.getAstrictRegion();
                    if (ObjectUtil.isNotNull(astrictRegion) && org.apache.commons.lang3.StringUtils.isNotBlank(astrictRegion.getRegionDesc())) {
                        String[] region = astrictRegion.getRegionDesc().split(",");
                        Optional<String> regionFlag = Stream.of(region).filter(x -> x.contains(province)).findFirst();
                        if (regionFlag.isPresent() && regionFlag.get().contains("全境")) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                    }
                    if (null != astrictRegion && org.apache.commons.lang3.StringUtils.isNotBlank(astrictRegion.getRegion())) {
                        String[] region = astrictRegion.getRegion().split(",");
                        Optional<String> regionFlag = Stream.of(region).filter(x -> x.equals(finalCity)).findFirst();
                        Optional<String> areaRegionFlag = Stream.of(region).filter(x -> x.equals(orders.getArea())).findFirst();
                        if (regionFlag.isPresent() && org.apache.commons.lang3.StringUtils.isNotBlank(regionFlag.get())) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                        if ( areaRegionFlag.isPresent() && org.apache.commons.lang3.StringUtils.isNotBlank(areaRegionFlag.get())) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                    }
                }
            });
        }

        //保存openid到用户表
        try {
            ordersDao.updateUserOpenId(orders.getUserId(),request.getOpenid());
        } catch (Exception e) {
            log.error("保存用户openid失败",e);
        }

        // 取出所有子订单
        List<OrdersInfo> ordersInfoList = ordersDao.getOrdersInfoList(orders.getId());
        // 取出第一条子订单
        OrdersInfo ordersInfo = ordersInfoList.get(0);
        // 检查是否存在支付订单号，如果存在，主动去微信查询订单结果
//        if (StringUtils.isNotBlank(orders.getTradeNo()) && !"UPAY".equals(request.getType())) {
//            try {
//                OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(orders.getTradeNo());
//                Map<String, String> map = wxServiceMap.get("APP-" + pay.getTradeType()).wxOrderQuery(orders.getTradeNo());
//                log.info("订单查询结果：{}", JSONObject.toJSONString(map));
//                if ("SUCCESS".equals(map.get("trade_state"))) {
//                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
//                } else if ("USERPAYING".equals(map.get("trade_state"))) {
//                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//                FeiShuUtil.sendMsg(String.format("wxDoUnifiedOrder接口调用微信下单查询失败,%s",e.getMessage()));
//            }
//        }

        // 获取订单号
        String resOrderNo = OrderUtils.getPayOrderCode(orders.getUserId());
        // 发起微信支付
        Map map;
        try {
            String productName = ordersInfo.getProductName().trim().replace("%", "").replace("+","");
            if (productName.length()>15){
                productName = productName.substring(0,10);
            }
            WxPayDto wxPayDto = WxPayDto.builder()
                    .body(productName.trim())
                    .resOrderNo(resOrderNo)
                    .realTotalMoney(String.valueOf(Integer.valueOf(orders.getRealTotalMoney()
                            .multiply(new BigDecimal(100))
                            .setScale(0)
                            .intValue())))
                    .openid(request.getOpenid())
                    .productId(ordersInfo.getProductId())
                    .orderNo(orders.getOrderNo())
                    .token(orders.getH5Token())
                    .wayCode(request.getWayCode())
                    .sourcePlatform(request.getSourcePlatform())
                    .build();
            if ("HFTX".equals(request.getType())){
                wxPayDto.setRealTotalMoney(orders.getRealTotalMoney().toString());
            }
            log.info("调取微信或第三方支付：req: {}", JSONObject.toJSONString(wxPayDto));
            map = wxServiceMap.get("APP-" + request.getType()).doUnifiedOrder(wxPayDto);
            log.info("调取微信或第三方支付结果：res: {}", JSONObject.toJSONString(map));
        } catch (Exception e) {
            log.error("==========》调微信失败e :{}", GlobalExceptionHandler.getExceptionToString(e));
            FeiShuUtil.sendMsg(String.format("调取第三方支付失败,%s",e.getMessage()));
            throw new ApiException(e);
        }
        OrdersPay pay = new OrdersPay();
        pay.setAmount(orders.getRealTotalMoney());
        pay.setOrderNo(orders.getOrderNo());
        pay.setResOrderNo(resOrderNo);
        pay.setPayType(PayPayTypeEnums.BEING_PROCESSED.getType());
        pay.setTradeType(request.getType());
        pay.setCreateTime(new Date());
        try {
            pay.setPayConfigId(Integer.parseInt(map.get("payConfigId").toString()));
            log.info("===pay==={}", pay.toString());
        } catch (Exception e) {
            log.error("===获取支付时的配置id异常==={}", e);
        }
        if (map.get("transaction_id")!=null){
            pay.setTransactionId(map.get("transaction_id").toString());
        }
        ordersPayMapper.insertSelective(pay);

        orders.setOrderRemarks(request.getDesc());
        orders.setTradeNo(pay.getResOrderNo());
        orders.setIsAnonymity(request.getIsAnonymity());
        orders.setRealNameId(request.getRealNameId());
        ordersMapper.updateByPrimaryKeySelective(orders);
        return map;
    }

    private void doSubSubsidy(Orders orders) {
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectOrderInfoByOrderId(orders.getId());
        // 删除补贴价格
        ordersInfoList.stream()
                .forEach(item -> {
                    // 扣除补贴价格
                    if ("OLD_FOR_NEW".equals(item.getActivityType())) {
                        String key = RedisConstants.SUBSIDYKEY_APP + orders.getH5Token();
                        if ("APP".equals(TokenUtil.getPlatformData().toUpperCase())) {
                            this.addUsedSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY_APP + orders.getH5Token(), orders.getUserId());
                        } else {
                            String subsidyObj = "";
                            try {
                                subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                            } catch (Exception e) {
                                log.info("===e==={}", e);
                            }
                            if (org.apache.commons.lang3.StringUtils.isNotEmpty(subsidyObj)) {
                                redisService.delete(key, item.getProductId().toString());
                                this.addUsedSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY_APP + orders.getH5Token());
                            }
                        }
                    }
                });
    }

    /**
     * 支付完成后更新yx_group_buy_user_rel表状态
     *
     * @param orderNo 订单编号
     * @param status  1-支付完成 0-未支付
     * @return
     */
    @Override
    public boolean updateGoupBuyUserRelStatus(String orderNo, Integer status) {
        return groupActivityService.updateGoupBuyUserRelStatus(orderNo, status);
    }

    private void addUsedSubsidy(OrdersInfo ordersInfo, String recordKey) {
        RecordSubsidyDataDto recordSubsidyDataDto = new RecordSubsidyDataDto();

        String recordSubsidyObj = redisService.get(recordKey);
        if (StringUtils.isNotEmpty(recordSubsidyObj)) {
            recordSubsidyDataDto = com.alibaba.fastjson.JSONObject.parseObject(recordSubsidyObj, RecordSubsidyDataDto.class);
        }

        BigDecimal received = Optional.ofNullable(recordSubsidyDataDto.getReceived())
                .orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal used = Optional.ofNullable(recordSubsidyDataDto.getUsed())
                .orElse(BigDecimal.ZERO)
                .add(ordersInfo.getActivityMax()).setScale(2, BigDecimal.ROUND_HALF_UP);

        if (used.compareTo(received) > 0) {
            received = used;
        }

        recordSubsidyDataDto.setUsed(used);
        recordSubsidyDataDto.setReceived(received);
        recordSubsidyDataDto.setToken(Optional.ofNullable(recordSubsidyDataDto.getToken()).orElse(TokenUtil.getToken()));
        recordSubsidyDataDto.setReceiveTime(Optional.ofNullable(recordSubsidyDataDto.getReceiveTime()).orElse(new Date()));

        redisService.set(recordKey, com.gexin.fastjson.JSON.toJSONString(recordSubsidyDataDto));
        redisService.expire(recordKey, ExpireTimeConstant.SUBSIDY_DATA_TIME);
    }

    private void addUsedSubsidy(OrdersInfo ordersInfo, String recordKey, Integer userId) {
        RecordSubsidyDataDto recordSubsidyDataDto = new RecordSubsidyDataDto();

        String recordSubsidyObj = redisService.get(recordKey);
        if (StringUtils.isNotEmpty(recordSubsidyObj)) {
            recordSubsidyDataDto = com.alibaba.fastjson.JSONObject.parseObject(recordSubsidyObj, RecordSubsidyDataDto.class);
        }

        BigDecimal received = Optional.ofNullable(recordSubsidyDataDto.getReceived())
                .orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal used = Optional.ofNullable(recordSubsidyDataDto.getUsed())
                .orElse(BigDecimal.ZERO)
                .add(ordersInfo.getActivityMax()).setScale(2, BigDecimal.ROUND_HALF_UP);

        if (used.compareTo(received) > 0) {
            received = used;
        }

        recordSubsidyDataDto.setUsed(used);
        recordSubsidyDataDto.setReceived(received);
        recordSubsidyDataDto.setToken(Optional.ofNullable(recordSubsidyDataDto.getToken()).orElse(TokenUtil.getToken()));
        recordSubsidyDataDto.setReceiveTime(Optional.ofNullable(recordSubsidyDataDto.getReceiveTime()).orElse(new Date()));

        redisService.set(recordKey, com.gexin.fastjson.JSON.toJSONString(recordSubsidyDataDto));
        redisService.expire(recordKey, ExpireTimeConstant.SUBSIDY_DATA_TIME);
        log.info("===userId={},received={}===", userId, received);
        redisService.set(RedisConstants.RECORD_SUBSIDYKEY_USE_APP + userId, String.valueOf(received));
        redisService.expire(RedisConstants.RECORD_SUBSIDYKEY_USE_APP + userId, Integer.parseInt(subsidyDay) * 24 * 60 * 60);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object h5WxDoUnifiedOrder(UnifiedOrderRequest request, UsersResponse usersResponse) {
        Orders orders = null;
        if(StringUtils.isNotBlank(request.getOrderNo())){
            orders = ordersDao.queryOrdersByOrderNo(request.getOrderNo());
        } else{
            orders = ordersMapper.selectByPrimaryKey(request.getOrderId());
        }
        if (orders ==null){
            throw new ApiException("订单不存在,请重新下单或者联系在线客服!");
        }
        //校验商品收货地址
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(orders.getId());
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        Orders finalOrders = orders;
        if ("1".equals(yunfeiSwitch)) {
            ordersInfoList.stream().forEach(ordersInfo -> {
                //获取运费模板
                FreightTemplateResponse freightTemplateResponse = getFreightTemplateResponse(ordersInfo.getProductId());
                if (null != freightTemplateResponse) {
                    //判断是否在限制地区
                    YxAstrictRegionResponse astrictRegion = freightTemplateResponse.getAstrictRegion();
                    if (ObjectUtil.isNotNull(astrictRegion) && org.apache.commons.lang3.StringUtils.isNotBlank(astrictRegion.getRegionDesc())) {
                        String[] region = astrictRegion.getRegionDesc().split(",");
                        Optional<String> regionFlag = Stream.of(region).filter(x -> x.contains(finalOrders.getProvince())).findFirst();
                        if (regionFlag.isPresent() && regionFlag.get().contains("全境")) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                    }
                    if (null != astrictRegion && StringUtils.isNotBlank(astrictRegion.getRegion())) {
                        String[] region = astrictRegion.getRegion().split(",");
//                        region = ArrayUtil.add(region, regionAddress);
                        Optional<String> regionFlag = Stream.of(region).filter(x -> x.equals(finalOrders.getCity())).findFirst();
                        Optional<String> areaRegionFlag = Stream.of(region).filter(x -> x.equals(finalOrders.getArea())).findFirst();
                        if (regionFlag.isPresent() && StringUtils.isNotBlank(regionFlag.get())) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                        if ( areaRegionFlag.isPresent() && StringUtils.isNotBlank(areaRegionFlag.get())) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                    }
                }
            });
        }

        Map<String, String> map = new HashMap<>();
        if (StringUtils.isEmpty(orders.getUserAddress()) || StringUtils.isEmpty(orders.getTel())) {
            throw new ApiException(ResultCode.NOT_USER_ADDRESS_ERROR);
        }
        if (IsPayConstant.YES.equals(orders.getIsPay())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PAID));
        }
        //敏感地址限制
        if (org.apache.commons.lang3.StringUtils.isNotBlank(orders.getUserAddress()) && blackAddress!=null){
            String[] blackAddressList = blackAddress.split(",");
            for (String bd : blackAddressList) {
                if (orders.getUserAddress().contains(bd)){
                    throw new ApiException("该地区不可下单,-3");
                }
            }
        }

        // 检查是否存在支付订单号，如果存在，主动去微信查询订单结果
        if (StringUtils.isNotBlank(orders.getTradeNo())) {
            try {
                OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(orders.getTradeNo());
                String key;
                if(!pay.getTradeType().startsWith("H5-")){
                    key = "H5-" + pay.getTradeType();
                }else {
                    key = pay.getTradeType();
                }
                Map<String, String> resMap = wxServiceMap.get(key).wxOrderQuery(orders.getTradeNo());
                log.info("订单查询结果：{}", JSONObject.toJSONString(resMap));
                if ("SUCCESS".equals(resMap.get("return_code"))) {
                    // 成功
                    if ("SUCCESS".equals(resMap.get("trade_state"))) {
                        throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
                    } else if ("USERPAYING".equals(resMap.get("trade_state"))) {
                        throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
                    }
                }
            } catch (Exception e) {
                log.error("h5预支付查询报错,{},{}",orders.getTradeNo(),e);
                FeiShuUtil.sendMsg(String.format("h5预支付查询报错,%s,%s",orders.getTradeNo(),e.getMessage()));
                throw new ApiException(e.getMessage());
            }
        }
        request.setWalletMoneyFlag(Optional.ofNullable(request.getWalletMoneyFlag()).orElse(0));
        // 校验用户余额
        if (request.getWalletMoneyFlag() == 1) {
            if (usersResponse.getMoney().compareTo(new BigDecimal(0)) == -1) {
                request.setWalletMoneyFlag(0);
            }
        }
        // 获取订单号
        String resOrderNo = OrderUtils.getPayOrderCode(orders.getUserId());

        // 取出第一条子订单
        OrdersInfo ordersInfo = ordersInfoList.get(0);

        OrdersPay pay = new OrdersPay();
        pay.setAmount(orders.getRealTotalMoney());
        pay.setOrderNo(orders.getOrderNo());
        pay.setResOrderNo(resOrderNo);
        pay.setPayType(PayPayTypeEnums.BEING_PROCESSED.getType());
        pay.setTradeType(request.getType());
        pay.setCreateTime(new Date());

//        try{
//            OrdersPayExample ordersPayExample = new OrdersPayExample();
//            ordersPayExample.createCriteria().andOrderNoEqualTo(orders.getOrderNo()).andPayTypeEqualTo(com.ytjj.common.enums.PayPayTypeEnums.FAIL.getType());
//            List<OrdersPay> ordersPays = ordersPayMapper.selectByExample(ordersPayExample);
//            if (!CollectionUtils.isEmpty(ordersPays) && ordersPays.size()>=2) {
//                FeiShuUtil.sendMsg(String.format("订单号为:%s已经支付失败超过2次,请查明原因！！！",orders.getOrderNo()));
//            }
//        }catch (Exception e) {
//
//        }
        //Adapay h5小程序预支付
        if (WxPayConstant.H5_ADAPAY_MINI.equals("H5-" + request.getType())) {
            pay.setTradeType("H5-"+request.getType());
            map = this.adapayWxDoUnifiedOrder(resOrderNo,orders.getRealTotalMoney(),ordersInfo.getProductName(),null,orders.getId(),null);
        } else {
            String productName = ordersInfo.getProductName().trim().replaceAll("%","");
            if (productName.length() > 30) {
                productName = productName.substring(0, 20);
            }
            // 发起微信支付
            try {
                map = wxServiceMap.get("H5-" + request.getType()).doUnifiedOrder(
                        WxPayDto.builder()
                                .body(productName)
                                .company(CompanyConstant.PLATFORM)
                                .openid(request.getOpenid())
                                .resOrderNo(resOrderNo)
                                .realTotalMoney(String.valueOf(Integer.valueOf(orders.getRealTotalMoney()
                                        .multiply(new BigDecimal(100))
                                        .setScale(0)
                                        .intValue())))
                                .token(usersResponse.getToken())
                                .productId(ordersInfo.getProductId())
                                .build()
                );
                try {
                    pay.setPayConfigId(Integer.parseInt(map.get("payConfigId")));
                } catch (Exception e) {
                    log.error("===获取支付时的配置id异常==={}", e);
                }
            } catch (Exception e) {
//                try {
//                    //自动转到另外一个商户号
//                    map = wxServiceMap.get("H5-MWEB2").doUnifiedOrder(
//                            WxPayDto.builder()
//                                    .body(productName)
//                                    .company(CompanyConstant.PLATFORM)
//                                    .openid(request.getOpenid())
//                                    .resOrderNo(resOrderNo)
//                                    .realTotalMoney(String.valueOf(Integer.valueOf(orders.getRealTotalMoney()
//                                            .multiply(new BigDecimal(100))
//                                            .setScale(0)
//                                            .intValue())))
//                                    .token(usersResponse.getToken())
//                                    .productId(ordersInfo.getProductId())
//                                    .build()
//                    );
//                    try {
//                        pay.setPayConfigId(Integer.parseInt(map.get("payConfigId")));
//                    } catch (Exception x) {
//                        log.error("===获取支付时的配置id异常==={}", x);
//                    }
//                } catch (Exception ex) {
//                    ex.printStackTrace();
                    log.error("==========》调微信失败e:{}", e);
                    FeiShuUtil.sendMsg(String.format("调用微信h5下单接口失败,%s",e.getMessage()));
//                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PAY_FAILED));
//                }
            }
            ordersPayMapper.insertSelective(pay);
            map.put("payOrderId", String.valueOf(pay.getId()));
            if (StringUtil.isNotEmpty(map.get("redirect_url"))) {
                String redirectUrl = map.get("redirect_url").replace("ORDER_ID", String.valueOf(orders.getId())).replace("PAY_ID", String.valueOf(pay.getId())).replace("ORDER_NO",orders.getOrderNo());
                if (!StringUtils.isBlank(request.getSourcePlatform())) {
                    List<String> taoxingou_return_url_list = null;
                    if (StringUtils.isNotEmpty(paySucReturnUrl)) {
                        taoxingou_return_url_list = Arrays.asList(paySucReturnUrl.split(","));
                    }
                    if (null != taoxingou_return_url_list && taoxingou_return_url_list.contains(request.getSourcePlatform())) {
                        redirectUrl = redirectUrl.replace("mall.XXXX.com", request.getSourcePlatform() + ".XXXX.com");
                    } else {
                        redirectUrl = redirectUrl.replace("https://mall.XXXX.com/pages/order/orderDetails.html", request.getSourcePlatform());
                    }
                }
                String channel = TokenUtil.getChannel();
                if (StringUtil.isNotEmpty(channel)) {
                    if (!channel.contains("old")) {
                        redirectUrl = redirectUrl + "&channel=" + channel + "-old";
                    } else {
                        redirectUrl = redirectUrl + "&channel=" + channel;
                    }
                }
                if(!StringUtils.isEmpty(orders.getH5Token())){
                    redirectUrl = redirectUrl + "&token="+orders.getH5Token();
                }
                map.put("redirect_url", redirectUrl);
                log.info("==========redirect_url:{}",redirectUrl);

            }
        }
        //设置用户唯一标识
        usersGetuiInfoService.updateUserVisitId(orders.getUserId(),TokenUtil.getVisitorId());
        orders.setOrderRemarks(request.getDesc());
        orders.setTradeNo(pay.getResOrderNo());
        orders.setIsAnonymity(request.getIsAnonymity());
        orders.setIsInvoice(null == request.getIsInvoice() ? 0 : request.getIsInvoice());
        ordersMapper.updateByPrimaryKeySelective(orders);

        return map;
    }

    /**
     * Adapay h5微信小程序预支付
     */
    public Map<String,String> adapayWxDoUnifiedOrder(String tradeNo,BigDecimal realTotalMoney,String productName,String goodsDesc,Integer payId,Integer orderId) {
        Map<String,String> map = new HashMap<>();
        try {
            map = wxServiceMap.get(WxPayConstant.H5_ADAPAY_MINI).doUnifiedOrder(new AdapayH5MiniPayDto()
                    .setTradeNo(tradeNo)
                    .setProductName(productName.trim())
                    .setGoodsDesc(goodsDesc)
                    .setRealTotalMoney(String.valueOf(realTotalMoney.setScale(2,RoundingMode.CEILING))).setOrderId(orderId).setPayId(payId));
            Map<String,String> expend = JSON.parseObject (JSON.toJSONString(map.get("expend")), Map.class);
            if(!CollectionUtils.isEmpty(expend)){
                map.put("redirect_url",expend.get("wx_h5_pay_url"));
            }else {
                throw new RuntimeException("adayPay h5小程序响应失败！");
            }
        } catch (Exception e) {
            log.error("==========》调Adapay微信小程序失败e:{}", e);
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PAY_FAILED));
        }
        return map;
    }

    /**
     * 查询Adapay h5微信小程序当前支付状态
     * @param tradeNo
     * @return Map<String,String>
     */
    public Map<String,String> queryAdapayOrder(String tradeNo){
        Map<String,String> map = new HashMap<>();
        try {
            map = wxServiceMap.get(WxPayConstant.H5_ADAPAY_MINI).wxOrderQuery(tradeNo);
            if (null != map) {
                log.info("adapay h5 微信小程序订单查询结果：{}", JSONObject.toJSONString(map));
                String response = map.get("status");
                if ("succeeded".equals(response)) {
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
                } else if ("pending".equals(response)) {
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_PAYMENT));
                }
            }
        } catch (Exception e) {
            log.error("==========》调Adapay微信小程序查询支付状态失败e:{}", e);
        }
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cashOnDelivery(UnifiedOrderRequest request) {
        Orders orders = ordersMapper.selectByPrimaryKey(request.getOrderId());
        // 直接修改订单状态
        orders.setOrderRemarks(request.getDesc());
        orders.setIsAnonymity(request.getIsAnonymity());
        orders.setPayType(OrderPayTypeEnums.pay_delivery.name());
        orders.setIsPay(IsPayConstant.NO);
        orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
        orders.setPayTime(new Date());
        if (request.getAddressId() != null) {
            DefaultAddressDto address = usersClient.getOneAddress(orders.getUserId(), request.getAddressId());
            orders.setProvince(address.getProvince());
            orders.setCity(address.getCity());
            orders.setAddress(address.getAddress());
            orders.setArea(address.getArea());
            orders.setUserAddress(address.getProvince() + address.getCity() + address.getArea() + address.getAddress());
            orders.setUserName(address.getName());
            orders.setUserPhone(address.getTel());
        }
        orders.setRealNameId(request.getRealNameId());
        ordersMapper.updateByPrimaryKeySelective(orders);

        // 获取订单明细
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria()
                .andOrderIdEqualTo(orders.getId());
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        ordersInfoList.stream()
                .forEach(item -> {
                    // 修改订单详情状态
                    OrdersInfo ordersInfo = new OrdersInfo();
                    ordersInfo.setId(item.getId());
                    ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                    ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                    try {
                        if ("h5".equals(TokenUtil.getPlatformData())) {
                            String tokenUser = redisService.get(orders.getH5Token());
                            // 商品 减库存 加销量 店家加销量
                            productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(), tokenUser, item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), orders.getUserId());
                        } else {
                            // 商品 减库存 加销量 店家加销量
                            productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(), item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), orders.getUserId());
                        }
                    } catch (Exception e) {
                        log.error(GlobalExceptionHandler.getExceptionToString(e));
                        log.error("减库存发生异常 订单id :{}", item.getId());
                    }
                    log.info("===platformData==={}", TokenUtil.getPlatformData());
                    if ("h5".equals(TokenUtil.getPlatformData())) {
                        // 删除补贴价格
                        if ("OLD_FOR_NEW".equals(item.getActivityType())) {
                            String key = RedisConstants.SUBSIDYKEY + orders.getH5Token();
                            String subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                            if (StringUtils.isNotEmpty(subsidyObj)) {
                                redisService.delete(key, item.getProductId().toString());
                                this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, orders.getH5Token());
                            }
                        }
                        // 扣除用户的红包余额
                        if ("CASH_COUPON".equals(item.getActivityType())) {
                            this.addUsedActivityMax(item.getActivityMax(), RedisConstants.RETURN_COUPON + orders.getH5Token());//记录用户使用红包金额
                        }
                        //
                        if ("RETURN_COUPON".equals(item.getActivityType())) {
                            this.addReturnCoupon(item.getActivityMax(), RedisConstants.RETURN_COUPON + orders.getH5Token());//记录用户返现红包金额
                        }
                    } else {
                        try {
                            // 删除补贴价格
                            if ("OLD_FOR_NEW".equals(item.getActivityType())) {
                                String key = RedisConstants.SUBSIDYKEY_APP + orders.getH5Token();
                                if ("APP".equals(TokenUtil.getPlatformData().toUpperCase())) {
                                    this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY_APP, orders.getH5Token(), orders.getUserId());
                                } else {
                                    String subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                                    if (StringUtils.isNotEmpty(subsidyObj)) {
                                        redisService.delete(key, item.getProductId().toString());
                                        this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY_APP, orders.getH5Token());
                                    }
                                }
                            }
                            // 扣除用户的红包余额
                            if ("CASH_COUPON".equals(item.getActivityType())) {
                                this.addUsedActivityMax(item.getActivityMax(), RedisConstants.RETURN_COUPON_APP + orders.getH5Token());//记录用户使用红包金额
                            }
                            //
                            if ("RETURN_COUPON".equals(item.getActivityType())) {
                                this.addReturnCoupon(item.getActivityMax(), RedisConstants.RETURN_COUPON_APP + orders.getH5Token());//记录用户返现红包金额
                            }
                        } catch (Exception e) {
                        }
                    }

                });
    }

    @Override
    public Orders getById(Integer orderId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        return orders;
    }

    @Override
    public Integer selectByorderNo(String orderNo) {
        return ordersMapper.selectByorderNo(orderNo);
    }

    @Override
    public Integer queryOrderNumByDynamicId(List<Integer> dynamicIds, Integer type) {

        Integer result = 0;
        switch (type) {
            case 1:
                result = ordersMapper.countByDynamicIdsByDay(dynamicIds);
                break;
            case 2:
                result = ordersMapper.countByDynamicIdsByWeek(dynamicIds);
                break;
            case 3:
                OrdersExample ordersExample = new OrdersExample();
                OrdersExample.Criteria criteria = ordersExample.createCriteria();
                criteria.andDynamicIdIn(dynamicIds).andIsPayEqualTo(OrdersPayStatusEnum.PAY.getValue());
                long num = ordersMapper.countByExample(ordersExample);
                result = Integer.parseInt(String.valueOf(num));
                break;
            default:
                break;
        }

        return result;
    }

    @Override
    public int selectOrdersZhuanShu(Integer userId) {
        return ordersMapper.selectOrdersZhuanShu(userId);
    }

    @Override
    public Orders getByOrderNo(String orderNo) {
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andOrderNoEqualTo(orderNo);
        List<Orders> list = ordersMapper.selectByExample(ordersExample);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }


    @Resource
    private PhoneRechargeMapper phoneRechargeMapper;

    @Override
    public Object h5WxDoUnifiedPhoneOrder(UnifiedOrderPhoneRequest request, UsersResponse usersResponse) {

        PhoneRechargeConfig phoneRechargeConfig = phoneRechargeConfigMapper.selectByPrimaryKey(request.getRechargeId());
        // 生成支付订单
        PhoneRecharge phoneRecharge = new PhoneRecharge();
        String resOrderNo = OrderUtils.getPhoneOrderCode();
        phoneRecharge.setOrderNo(resOrderNo);
        phoneRecharge.setPhone(request.getPhone());
        phoneRecharge.setOperators(request.getOperators());
        phoneRecharge.setPlatform(TokenUtil.getPlatformData());
        phoneRecharge.setChannel(TokenUtil.getChannel());
        phoneRecharge.setUuid(TokenUtil.getToken());
        phoneRecharge.setStatus(1);                         // 支付中
        phoneRecharge.setPayType(PayTypeEnums.wx.name());
        phoneRecharge.setDenomination(phoneRechargeConfig.getDenomination());
        phoneRecharge.setGiveIntegral(phoneRechargeConfig.getGiveIntegral());
        phoneRecharge.setPrice(phoneRechargeConfig.getPrice());
        phoneRecharge.setErrorStatus(0);
        phoneRecharge.setCreateTime(new Date());
        phoneRecharge.setType("H5-ISV-MWEB");
        phoneRechargeMapper.insert(phoneRecharge);


        Map<String, String> map;
        // 发起微信支付
        try {
            map = wxServiceMap.get("H5-ISV-MWEB").doUnifiedRechargeOrder(WxPayDto.builder()
                    .body("XXXX优品2")
                    .company(COMPANY)
                    .resOrderNo(resOrderNo)
                    .realTotalMoney(String.valueOf(phoneRechargeConfig.getPrice()))
                    .token(TokenUtil.getToken())
                    .build());
//            map = this.doUnifiedOrder(
//                    WxH5PayDto.builder()
//                            .body("XXXX优品-商城")
//                            .company(CompanyConstant.PLATFORM)
//                            .resOrderNo(resOrderNo)
//                            .realTotalMoney(String.valueOf(phoneRechargeConfig.getPrice()))
//                            .token(TokenUtil.getToken())
//                            .build());
        } catch (Exception e) {
            log.error("==========》调微信手机充值失败e:{}", GlobalExceptionHandler.getExceptionToString(e));
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PAY_FAILED));
        }

        if (StringUtil.isNotEmpty(map.get("redirect_url"))) {
            String redirectUrl = map.get("redirect_url");
            String channel = TokenUtil.getChannel();

//            if(!StringUtils.isBlank(request.getSourcePlatform())){//https://sale.quanminyanxuan.com/packageA/pages/order/callRecharge?orderId=ORDER_ID
//                String buyUrl = "https://buy.quanminyanxuan.com/pages/order/rechargePay?orderId=ORDER_ID";
//                redirectUrl = buyUrl.replace("ORDER_ID", String.valueOf(phoneRecharge.getId()));
//                redirectUrl = redirectUrl+"&sourcePlatform="+request.getSourcePlatform();
//
//            }
            if ("mall".equalsIgnoreCase(TokenUtil.getSourcePlatform())) {
                redirectUrl = "https://mall.XXXX.com/pages/order/callRecharge.html?orderId=ORDER_ID";
            } else if ("h5".equalsIgnoreCase(TokenUtil.getSourcePlatform())) {
                redirectUrl = "https://guobao.XXXX.com/pages/order/callRecharge.html?orderId=ORDER_ID";
            } else if ("dh".equalsIgnoreCase(TokenUtil.getSourcePlatform())) {
                redirectUrl = "https://dh.XXXX.com/pages/order/callRecharge.html?orderId=ORDER_ID";
            } else if ("by".equalsIgnoreCase(TokenUtil.getSourcePlatform())) {
                redirectUrl = "https://by.XXXX.com/pages/order/callRecharge.html?orderId=ORDER_ID";
            } else if ("svip".equalsIgnoreCase(TokenUtil.getSourcePlatform())) {
                redirectUrl = "https://svip.XXXX.com/pages/order/callRecharge.html?orderId=ORDER_ID";
            } else if ("platform".equalsIgnoreCase(TokenUtil.getSourcePlatform())) {
                redirectUrl = "https://platform.XXXX.com/pages/order/callRecharge.html?orderId=ORDER_ID";
            }
            redirectUrl = redirectUrl.replace("ORDER_ID", String.valueOf(phoneRecharge.getId()));
            if (StringUtil.isNotEmpty(channel)) {
                if (!channel.contains("old")) {
                    redirectUrl = redirectUrl + "&channel=" + channel + "-old";
                } else {
                    redirectUrl = redirectUrl + "&channel=" + channel;
                }
            }
            map.put("redirect_url", redirectUrl);
        }

        return map;
    }

    private Map<String, String> doUnifiedOrder(WxH5PayDto wxH5PayDto) throws Exception {
        String TRADE_TYPE = "PHONE_CHARGES";
        PayConfig payConfig = ordersDao.getPayConfigByCompany(COMPANY, "H5", TRADE_TYPE);
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);

        Map<String, String> data = new HashMap<>();
        data.put("appid", payConfig.getAppid());
        data.put("attach", wxH5PayDto.getToken());
        data.put("body", wxH5PayDto.getBody());
        data.put("mch_id", payConfig.getMchId());
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        data.put("notify_url", payConfig.getNotifyUrl());
        data.put("out_trade_no", wxH5PayDto.getResOrderNo());
        data.put("spbill_create_ip", payConfig.getSpbillCreateIp());
        data.put("total_fee", wxH5PayDto.getRealTotalMoney());
        data.put("trade_type", "MWEB");
        data.put("scene_info", "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"http://www.quanminyanxuan.com\",\"wap_name\": \"XXXX优品\"}}");

        WXPay wxpay = new WXPay(myWxConfig, WXPayConstants.SignType.MD5);
        data.put("sign", WXPayUtil.generateSignature(data, payConfig.getWxKey(),
                WXPayConstants.SignType.MD5));

        Map<String, String> response = wxpay.unifiedOrder(data);
        log.info(JSONObject.toJSONString(response));
        if ("SUCCESS".equals(response.get("return_code"))) {
            Map<String, String> param = new HashMap<>();
            param.put("mweb_url", response.get("mweb_url"));
            param.put("redirect_url", payConfig.getRedirectUrl());
            return param;
        }
        throw new Exception("下单失败");
    }

    @Override
    public OrderResponse queryOrderInfoByChildOrderNo(String childOrderNo, String source, UsersResponse usersResponse) {
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andChildOrderNoEqualTo(childOrderNo);
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        if (CollectionUtils.isEmpty(ordersInfoList)) {
            throw new ApiException("订单不存在!");
        }
        OrdersInfo ordersInfo = ordersInfoList.get(0);
        return queryAppOrderDetail(ordersInfo, usersResponse);
    }

    private OrderResponse queryAppOrderDetailByH5(OrdersInfo ordersInfo, UsersResponse usersResponse) {
        String companyNo = ordersInfo.getExpressCompanyNo();
        String expressNo = ordersInfo.getExpressNo();
        OrderResponse response = new OrderResponse();
        //查运费
        List<OrdersInfoFreightDto> ordersInfoFreightDtos = ordersInfoMapper.selectOrdersInfoFreightDto(ordersInfo.getChildOrderNo());
        BigDecimal zhi = new BigDecimal(0);
        for (OrdersInfoFreightDto ordersInfoFreightDto : ordersInfoFreightDtos) {
            zhi = ordersInfoFreightDto.getFreight().add(zhi);
        }
        response.setFreights(zhi);
        response.setOrderInfoStatus(ordersInfo.getOrderinfoStatus());
        // 查是否有延期备注
        List<OrdersDelay> delayRemark = orderInfoDao.findDelayRemark(ordersInfo.getId());
        if (!CollectionUtils.isEmpty(delayRemark) && delayRemark.size() > 0) {
            response.setOrderDelay(ordersInfo.getOrderinfoStatus().equals("1") ?
                    delayRemark.get(0).getDelayRemark() : ordersInfo.getOrderinfoStatus().equals("2") ?
                    delayRemark.get(0).getDelayRemark() : null);
        }

        // -----------------订单主表信息-----------------
        Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());
        log.info("orders.userId={}, currentUserId={}", orders.getUserId(), null == usersResponse ? null : usersResponse.getId());
        // 订单原总价格
        response.setTotalMoney(ordersInfo.getProductOprice().multiply(new BigDecimal(ordersInfo.getProductSum())));
        // 订单实付总价格
        List<OrderDisparitiesRefundResponse> orderDisparitiesRefunds = orderDisparitiesRefundListMapper.querySuccessByOrderNo(orders.getOrderNo());
        BigDecimal refundMoney= BigDecimal.ZERO;
        if (!org.springframework.util.CollectionUtils.isEmpty(orderDisparitiesRefunds)) {
            refundMoney = orderDisparitiesRefunds.stream().map(item -> ObjectUtils.isEmpty(item.getAmount()) ? new BigDecimal(0) : item.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        response.setRealTotalMoney(orders.getRealTotalMoney().subtract(refundMoney));
        // 订单编号
        response.setOrderNo(orders.getOrderNo());
        // 运费
//        response.setFreight(new BigDecimal(0));
        // 支付状态(明细的状态)
        response.setPayStatus(Integer.parseInt(ordersInfo.getOrderinfoStatus() == null ? "0" : ordersInfo.getOrderinfoStatus()));
        // 支付方式
        response.setPaySource(orders.getPaySource());
        if (StringUtil.isEmpty(response.getPaySource())) {
            response.setPaySource("wallet");
        }
        //支付类型
        response.setPayType(orders.getPayType());
        // 支付时间
        response.setPayTime(orders.getPayTime());
        // 订单创建时间
        response.setCreateTime(orders.getCreateTime());
        // 收货地址
        DefaultAddressDto defaultAddressDto = new DefaultAddressDto()
                .setName(orders.getUserName())
                .setTel(orders.getUserPhone())
                .setProvince(orders.getProvince())
                .setCity(orders.getCity())
                .setArea(orders.getArea())
                .setAddress(orders.getAddress())
                .setAddressAll(orders.getUserAddress());
        response.setAddress(defaultAddressDto);

        // -------------------订单详情-------------------------
        List<OrderInfoResponse> ordersInfoList = new ArrayList<>();
        if (orders.getIsPay() == 1) {
            if (!StringUtil.isEmpty(ordersInfo.getChildOrderNo())) {
                response.setOrderNo(ordersInfo.getChildOrderNo());
            }
            ordersInfo.setExpressNo(InfoAesUtil.aesExpressNo(ordersInfo.getExpressNo()));
            ordersInfo.setWarehouseName("");
            ordersInfo.setWarehouse("");
            ordersInfoList.add(new OrderInfoResponse(ordersInfo));
            OrderInfoResponse orderInfoResponse = ordersInfoList.get(0);

            Dynamic dynamic = ordersDao.findAllById(ordersInfo.getId());
            if (null != dynamic) {
                orderInfoResponse.setDynamicFlag(true);
                orderInfoResponse.setDynamicStatus(Integer.valueOf(dynamic.getStatus()));
            } else {
                orderInfoResponse.setDynamicFlag(false);
            }

        } else {
            // 订单原总价格
            response.setTotalMoney(orders.getTotalMoney());

            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(orders.getId());
            List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
            BigDecimal bigDecimal = new BigDecimal(0);
            for (OrdersInfo info : ordersInfos) {
                info.setExpressNo(InfoAesUtil.aesExpressNo(info.getExpressNo()));
                ordersInfo.setWarehouseName("");
                ordersInfo.setWarehouse("");
                ordersInfoList.add(new OrderInfoResponse(info));
                bigDecimal.add(info.getProductPrice());
            }

            // 订单实付总价格
            response.setRealTotalMoney(bigDecimal);

        }
        response.setOrderInfoList(ordersInfoList);
        // ----------------------------------------------------计算各种优惠价格总和---------------------------------------------------------------------
        Map<String, Object> discountType = new HashMap<>();
        // 积分
        BigDecimal cashScoreActivityMax = new BigDecimal(0);           // 积分
        BigDecimal cashScoreReducedPrice = new BigDecimal(0);           // 抵扣价格
        // 返积分
        BigDecimal returnScore = new BigDecimal(0);
        // 大额神券
        BigDecimal cashCouponReducedPrice = new BigDecimal(0);
        // 以旧换新
        BigDecimal oldForNewReducedPrice = new BigDecimal(0);

        BigDecimal activityMax = BigDecimal.ZERO;
        for (OrderInfoResponse item : ordersInfoList) {
            log.info("==========OrderInfoResponse============={}", JSONObject.toJSONString(item));
            // 只有 活动商品  + 不是直接购买  才累加优惠
            if (StringUtils.isNotBlank(item.getActivityType()) && item.getIsDirectbuy() != 1) {
                BigDecimal itemActivityMax = Optional.ofNullable(item.getActivityMax()).orElse(BigDecimal.ZERO);
                activityMax = activityMax.add(itemActivityMax);
                // 活动类型
                switch (item.getActivityType()) {
                    case "CASH_SCORE":
                        // 兑换积分
                        cashScoreActivityMax = cashScoreActivityMax.add(itemActivityMax);
                        cashScoreReducedPrice = cashScoreReducedPrice.add(item.getProductOprice().subtract(item.getProductPrice()));
                        break;
                    case "GET_SCORE":
                    case "NEW_USER":
                        // 新人首单返积分、返积分 统一加积分
                        returnScore = returnScore.add(itemActivityMax);
                        break;
                    case "CASH_COUPON":
                        cashCouponReducedPrice = cashCouponReducedPrice.add(itemActivityMax);
                        break;
                    case "OLD_FOR_NEW":
                        // 以旧换新
                        oldForNewReducedPrice = oldForNewReducedPrice.add(itemActivityMax);
                        break;
                }
            }
        }

        // 积分
        Map<String, Object> cashScore = new HashMap<>();
        cashScore.put("cashScoreActivityMax", cashScoreActivityMax.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScorePrice", cashScoreReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        discountType.put("cashScore", cashScore);
        // 返积分
        discountType.put("returnScore", returnScore.setScale(2, BigDecimal.ROUND_UP));
        // 大额神券
        discountType.put("cashCouponPrice", cashCouponReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        // 以旧换新
        discountType.put("oldForNewPrice", oldForNewReducedPrice.setScale(2, BigDecimal.ROUND_UP));

        // 平台立减
        BigDecimal platformPrice = ordersInfo.getProductOprice()
                .subtract(cashScoreReducedPrice)                // 积分抵扣
                .subtract(cashCouponReducedPrice)               // 优惠券
                .subtract(oldForNewReducedPrice)                // 以旧换新
                .subtract(ordersInfo.getProductPrice())           // 实际支付价格
                .setScale(2, BigDecimal.ROUND_UP);
        if (orders.getIsPay() == 0) {
            platformPrice = orders.getTotalMoney().subtract(orders.getRealTotalMoney()).subtract(activityMax).setScale(2, BigDecimal.ROUND_UP);
        }
        discountType.put("platformPrice", platformPrice);
        response.setDiscountType(discountType);
        try {
            response.setExpressFlag(0);
            OrdersPayExample example = new OrdersPayExample();
            example.createCriteria()
                    .andOrderNoEqualTo(orders.getOrderNo());
            List<OrdersPay> ordersPays = ordersPayMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(ordersPays)) {
                response.setExpressFlag(1);
            }
        } catch (Exception e) {
            log.error("===查询订单支付表数据异常==={}", e);
        }
        Boolean flag = true;//是否可以申请售后标识
        long time1 = new Date().getTime();//现在的时间
        //订单为已发货
        if (ordersInfo.getOrderinfoStatus().equals("2")) {
            Integer hour = 12 * 24;
            //已发货12天后不能申请售后
            Date date = getDate(ordersInfo.getDeliveryTime(), hour);//已发货12天后的时间
            long time = date.getTime();

            if (time1 > time) {
                flag = false;
            }
            if (!StringUtils.isEmpty(ordersInfo.getExpressNo())) {
                hour = 7 * 24;
            }
            if (null != ordersInfo.getDeliveryTime()) {
                response.setDeliveryExpirationTime(getDate(ordersInfo.getDeliveryTime(), hour));
            }
        } else if (ordersInfo.getOrderinfoStatus().equals("0")) {
            response.setPayExpirationTime(getDate(ordersInfo.getCreateTime(), 1));
        } else if (ordersInfo.getOrderinfoStatus().equals("3")) {
            long time = getDate(ordersInfo.getReceiveTime(), 7 * 24).getTime();
            if (time1 > time) {
                flag = false;
            }
        } else if (ordersInfo.getOrderinfoStatus().equals("4")) {
            response.setCloseRemarks(ordersInfo.getCloseRemarks());
        }
        response.setReturnFlag(0);
        ReturnGoodsExample returnGoodsExample = new ReturnGoodsExample();
        returnGoodsExample.createCriteria().andOrdersInfoIdEqualTo(ordersInfo.getId());
        returnGoodsExample.setOrderByClause("id desc");
        List<ReturnGoods> list = returnGoodsMapper.selectByExample(returnGoodsExample);
        if (list.size() > 0) {
            response.setReturnFlag(1);
            response.setServiceNo(list.get(0).getServiceNo());
        }
        if (orders.getIsPay() == 0) {
            List<OrderInfoResponse> orderInfoList = response.getOrderInfoList();
            AtomicReference<BigDecimal> realTotalMoney = new AtomicReference<>(new BigDecimal(0));
            orderInfoList.stream().forEach(orderInfo -> {
                realTotalMoney.set(realTotalMoney.get().add(orderInfo.getProductPrice().multiply(BigDecimal.valueOf(orderInfo.getProductSum()))));
            });
            response.setRealTotalMoney(realTotalMoney.get());
        }
        response.setApplyReturnFlag(flag);

        //
        List<OrderInfoResponse> orderInfoList = response.getOrderInfoList();
        final BigDecimal[] price = {BigDecimal.ZERO};
        final BigDecimal[] totalMoney = {BigDecimal.ZERO};
        orderInfoList.stream().forEach(orderInfoResponse -> {
            price[0] = price[0].add(orderInfoResponse.getProductPrice().multiply(BigDecimal.valueOf(orderInfoResponse.getProductSum())));
            totalMoney[0] = totalMoney[0].add(orderInfoResponse.getProductOprice().multiply(BigDecimal.valueOf(orderInfoResponse.getProductSum())));

        });
        response.setProductPriceAndFreights(price[0].add(zhi));
        response.setTotalMoney(totalMoney[0]);
        //查询订单物流
        response.setDeliveryResp(queryOrderExpressInfo(companyNo, expressNo));
        response.setTel(InfoAesUtil.aesPhone(response.getTel()));
        return response;
    }

    private OrderResponse queryAppOrderDetail(OrdersInfo ordersInfo, UsersResponse usersResponse) {
        OrderResponse response = new OrderResponse();
        //查运费
        List<OrdersInfoFreightDto> ordersInfoFreightDtos = ordersInfoMapper.selectOrdersInfoFreightDto(ordersInfo.getChildOrderNo());
        BigDecimal zhi = new BigDecimal(0);
        for (OrdersInfoFreightDto ordersInfoFreightDto : ordersInfoFreightDtos) {
            zhi = ordersInfoFreightDto.getFreight().add(zhi);
        }
        response.setFreights(zhi);

        // 查是否有延期备注
        List<OrdersDelay> delayRemark = orderInfoDao.findDelayRemark(ordersInfo.getId());
        if (!CollectionUtils.isEmpty(delayRemark) && delayRemark.size() > 0) {
            response.setOrderDelay(ordersInfo.getOrderinfoStatus().equals("1") ?
                    delayRemark.get(0).getDelayRemark() : ordersInfo.getOrderinfoStatus().equals("2") ?
                    delayRemark.get(0).getDelayRemark() : null);
        }

        // -----------------订单主表信息-----------------
        Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());
        log.info("orders.userId={}, currentUserId={}", orders.getUserId(), null == usersResponse ? null : usersResponse.getId());
        // 订单原总价格
        response.setTotalMoney(ordersInfo.getProductOprice().multiply(new BigDecimal(ordersInfo.getProductSum())));
        // 订单实付总价格
        response.setRealTotalMoney(ordersInfo.getProductPrice().multiply(new BigDecimal(ordersInfo.getProductSum())));
        // 订单编号
        response.setOrderNo(orders.getOrderNo());
        // 运费
//        response.setFreight(new BigDecimal(0));
        // 支付状态(明细的状态)
        response.setPayStatus(Integer.parseInt(ordersInfo.getOrderinfoStatus() == null ? "0" : ordersInfo.getOrderinfoStatus()));
        // 支付方式
        response.setPaySource(orders.getPaySource());
        if (StringUtil.isEmpty(response.getPaySource())) {
            response.setPaySource("wallet");
        }
        //支付类型
        response.setPayType(orders.getPayType());
        // 支付时间
        response.setPayTime(orders.getPayTime());
        // 订单创建时间
        response.setCreateTime(orders.getCreateTime());
        // 收货地址
        DefaultAddressDto defaultAddressDto = new DefaultAddressDto()
                .setName(orders.getUserName())
                .setTel(orders.getUserPhone())
                .setProvince(orders.getProvince())
                .setCity(orders.getCity())
                .setArea(orders.getArea())
                .setAddress(orders.getAddress())
                .setAddressAll(orders.getUserAddress());
        response.setAddress(defaultAddressDto);

        // -------------------订单详情-------------------------
        List<OrderInfoResponse> ordersInfoList = new ArrayList<>();
        if (orders.getIsPay() == 1) {
            if (!StringUtil.isEmpty(ordersInfo.getChildOrderNo())) {
                response.setOrderNo(ordersInfo.getChildOrderNo());
            }
            ordersInfoList.add(new OrderInfoResponse(ordersInfo));
            OrderInfoResponse orderInfoResponse = ordersInfoList.get(0);

            Dynamic dynamic = ordersDao.findAllById(ordersInfo.getId());
            if (null != dynamic) {
                orderInfoResponse.setDynamicFlag(true);
                orderInfoResponse.setDynamicStatus(Integer.valueOf(dynamic.getStatus()));
            } else {
                orderInfoResponse.setDynamicFlag(false);
            }

        } else {
            // 订单原总价格
            response.setTotalMoney(orders.getTotalMoney());

            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(orders.getId());
            List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
            BigDecimal bigDecimal = new BigDecimal(0);
            for (OrdersInfo info : ordersInfos) {
                ordersInfoList.add(new OrderInfoResponse(info));
                bigDecimal.add(info.getProductPrice());
            }

            // 订单实付总价格
            response.setRealTotalMoney(bigDecimal);

        }
        response.setOrderInfoList(ordersInfoList);

        // ----------------------------------------------------计算各种优惠价格总和---------------------------------------------------------------------
        Map<String, Object> discountType = new HashMap<>();
        // 积分
        BigDecimal cashScoreActivityMax = new BigDecimal(0);           // 积分
        BigDecimal cashScoreReducedPrice = new BigDecimal(0);           // 抵扣价格
        // 返积分
        BigDecimal returnScore = new BigDecimal(0);
        // 大额神券
        BigDecimal cashCouponReducedPrice = new BigDecimal(0);
        // 以旧换新
        BigDecimal oldForNewReducedPrice = new BigDecimal(0);

        BigDecimal activityMax = BigDecimal.ZERO;
        for (OrderInfoResponse item : ordersInfoList) {
            log.info("==========OrderInfoResponse============={}", JSONObject.toJSONString(item));
            // 只有 活动商品  + 不是直接购买  才累加优惠
            if (StringUtils.isNotBlank(item.getActivityType()) && item.getIsDirectbuy() != 1) {
                activityMax = activityMax.add(Optional.ofNullable(item.getActivityMax()).orElse(BigDecimal.ZERO));
                // 活动类型
                switch (item.getActivityType()) {
                    case "CASH_SCORE":
                        // 兑换积分
                        cashScoreActivityMax = cashScoreActivityMax.add(Optional.ofNullable(item.getActivityMax()).orElse(BigDecimal.ZERO));
                        cashScoreReducedPrice = cashScoreReducedPrice.add(item.getProductOprice().subtract(item.getProductPrice()));
                        break;
                    case "GET_SCORE":
                    case "NEW_USER":
                        // 新人首单返积分、返积分 统一加积分
                        returnScore = returnScore.add(Optional.ofNullable(item.getActivityMax()).orElse(BigDecimal.ZERO));
                        break;
                    case "CASH_COUPON":
                        cashCouponReducedPrice = cashCouponReducedPrice.add(Optional.ofNullable(item.getActivityMax()).orElse(BigDecimal.ZERO));
                        break;
                    case "OLD_FOR_NEW":
                        // 以旧换新
                        oldForNewReducedPrice = oldForNewReducedPrice.add(Optional.ofNullable(item.getActivityMax()).orElse(BigDecimal.ZERO));
                        break;
                }
            }
        }

        // 积分
        Map<String, Object> cashScore = new HashMap<>();
        cashScore.put("cashScoreActivityMax", cashScoreActivityMax.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScorePrice", cashScoreReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        discountType.put("cashScore", cashScore);
        // 返积分
        discountType.put("returnScore", returnScore.setScale(2, BigDecimal.ROUND_UP));
        // 大额神券
        discountType.put("cashCouponPrice", cashCouponReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        // 以旧换新
        discountType.put("oldForNewPrice", oldForNewReducedPrice.setScale(2, BigDecimal.ROUND_UP));

        // 平台立减
        BigDecimal platformPrice = ordersInfo.getProductOprice()
                .subtract(cashScoreReducedPrice)                // 积分抵扣
                .subtract(cashCouponReducedPrice)               // 优惠券
                .subtract(oldForNewReducedPrice)                // 以旧换新
                .subtract(ordersInfo.getProductPrice())           // 实际支付价格
                .setScale(2, BigDecimal.ROUND_UP);
        if (orders.getIsPay() == 0) {
            platformPrice = orders.getTotalMoney().subtract(orders.getRealTotalMoney()).subtract(activityMax).setScale(2, BigDecimal.ROUND_UP);
        }
        discountType.put("platformPrice", platformPrice);
        response.setDiscountType(discountType);
        try {
            response.setExpressFlag(0);
            OrdersPayExample example = new OrdersPayExample();
            example.createCriteria()
                    .andOrderNoEqualTo(orders.getOrderNo());
            List<OrdersPay> ordersPays = ordersPayMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(ordersPays)) {
                response.setExpressFlag(1);
            }
        } catch (Exception e) {
            log.error("===查询订单支付表数据异常==={}", e);
        }
        Boolean flag = true;//是否可以申请售后标识
        long time1 = new Date().getTime();//现在的时间
        //订单为已发货
        if (ordersInfo.getOrderinfoStatus().equals("2")) {
            Integer hour = 12 * 24;
            //已发货12天后不能申请售后
            Date date = getDate(ordersInfo.getDeliveryTime(), hour);//已发货12天后的时间
            long time = date.getTime();

            if (time1 > time) {
                flag = false;
            }
            if (!StringUtils.isEmpty(ordersInfo.getExpressNo())) {
                hour = 7 * 24;
            }
            if (null != ordersInfo.getDeliveryTime()) {
                response.setDeliveryExpirationTime(getDate(ordersInfo.getDeliveryTime(), hour));
            }
        } else if (ordersInfo.getOrderinfoStatus().equals("0")) {
            response.setPayExpirationTime(getDate(ordersInfo.getCreateTime(), 1));
        } else if (ordersInfo.getOrderinfoStatus().equals("3")) {
            long time = getDate(ordersInfo.getReceiveTime(), 7 * 24).getTime();
            if (time1 > time) {
                flag = false;
            }
        } else if (ordersInfo.getOrderinfoStatus().equals("4")) {
            response.setCloseRemarks(ordersInfo.getCloseRemarks());
        }
        response.setReturnFlag(0);
        ReturnGoodsExample returnGoodsExample = new ReturnGoodsExample();
        returnGoodsExample.createCriteria().andOrdersInfoIdEqualTo(ordersInfo.getId());
        returnGoodsExample.setOrderByClause("id desc");
        List<ReturnGoods> list = returnGoodsMapper.selectByExample(returnGoodsExample);
        if (list.size() > 0) {
            response.setReturnFlag(1);
            response.setServiceNo(list.get(0).getServiceNo());
        }
        if (orders.getIsPay() == 0) {
            List<OrderInfoResponse> orderInfoList = response.getOrderInfoList();
            AtomicReference<BigDecimal> realTotalMoney = new AtomicReference<>(new BigDecimal(0));
            orderInfoList.stream().forEach(orderInfo -> {
                realTotalMoney.set(realTotalMoney.get().add(orderInfo.getProductPrice().multiply(BigDecimal.valueOf(orderInfo.getProductSum()))));
            });
            response.setRealTotalMoney(realTotalMoney.get());
        }
        response.setApplyReturnFlag(flag);

        //
        List<OrderInfoResponse> orderInfoList = response.getOrderInfoList();
        final BigDecimal[] price = {BigDecimal.ZERO};
        final BigDecimal[] totalMoney = {BigDecimal.ZERO};
        orderInfoList.stream().forEach(orderInfoResponse -> {
            price[0] = price[0].add(orderInfoResponse.getProductPrice().multiply(BigDecimal.valueOf(orderInfoResponse.getProductSum())));
            totalMoney[0] = totalMoney[0].add(orderInfoResponse.getProductOprice().multiply(BigDecimal.valueOf(orderInfoResponse.getProductSum())));

        });
        response.setProductPriceAndFreights(price[0].add(zhi));
        response.setTotalMoney(totalMoney[0]);
        //查询订单物流
//        response.setDeliveryInfo(queryOrderExpress(ordersInfo));
        return response;
    }

    /**
     * 物流信息动态
     */
    private List<Object> queryOrderExpress(String companyNo, String expressNo) {
        Map<String, String> map = new HashMap<>();
        map.put("expressCompany", companyNo);
        map.put("expressNo", expressNo);
        String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/order/checkLogistics", map, supplyApiConfig.getHeadsMap());
        if (null != resultJson) {
            Map<String, String> res = null;
            try {
                Gson gson = new Gson();
                res = gson.fromJson(resultJson, new TypeToken<Map<String, String>>() {
                }.getType());
            } catch (Exception e) {

            }
            return JSONArray.parseArray(res.get("infoText"));
        }
        return new ArrayList<>();
    }

    /**
     * 物流信息动态
     */
    public Object queryOrderExpressInfo(String companyNo, String expressNo) {
        Map<String, String> map = new HashMap<>();
        map.put("expressCompany", companyNo);
        map.put("expressNo", expressNo);
        String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/order/checkLogistics", map, supplyApiConfig.getHeadsMap());
        Map<String,Object> resp = new HashMap<>();
        if (null != resultJson) {
            Map<String, String> res = null;
            try {
                Gson gson = new Gson();
                res = gson.fromJson(resultJson, new TypeToken<Map<String, String>>() {
                }.getType());
            } catch (Exception e) {
                log.error("解析快递出错{}",e);
            }
            resp.put("expressEno", res.get("expressEno"));
            resp.put("expressKey", res.get("expressKey"));
            resp.put("infoText", JSONArray.parseArray(res.get("infoText")));
            resp.put("status", res.get("status"));
        }
        return resp;
    }


    /**
     * 订单详情 （根据订单详情id查询数据）
     *
     * @param orderInfoId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderResponse queryOrderInfoById(Integer orderInfoId, String source, UsersResponse usersResponse) {
        OrderResponse response = new OrderResponse();

        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(orderInfoId);
        if (ordersInfo == null) {
            return new OrderResponse();
        }
        return queryAppOrderDetail(ordersInfo, usersResponse);
    }

    @Override
    public List<QueryTrackData> getLogisticsInfo(Integer orderInfoId) {
        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(orderInfoId);
        // 快递公司编码
        String expressCompanyNo = ordersInfo.getExpressCompanyNo();
        // 快递号
        String expressNo = ordersInfo.getExpressNo();
        if (StringUtils.isBlank(expressCompanyNo) || StringUtils.isBlank(expressNo)) {
            return null;
        }
        QueryTrack queryTrack = new QueryTrack();
        QueryTrackReq queryTrackReq = new QueryTrackReq();
        QueryTrackParam queryTrackParam = new QueryTrackParam();
        queryTrackParam.setCom(expressCompanyNo);
        queryTrackParam.setNum(expressNo);

        queryTrackReq.setParam(queryTrackParam);
        queryTrackReq.setCustomer(PropertiesReader.get("customer"));
        queryTrackReq.setSign(SignUtils.sign(new Gson().toJson(queryTrackParam) + PropertiesReader.get("key") + PropertiesReader.get("customer")));
        QueryTrackResp resp = queryTrack.queryTrack(queryTrackReq);
        log.info("快递100 手动查询结果：{}", JSONObject.toJSONString(resp));
        if ("200".equals(resp.getStatus())) {
            List<QueryTrackData> queryTrackDataList = resp.getData();
            return queryTrackDataList;
        }
        return null;
    }

    //此方法不再使用
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receivingGoods(Integer orderInfoId) {
        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(orderInfoId);
        // 修改订单详情的状态
        OrdersInfo oi = new OrdersInfo();
        oi.setId(ordersInfo.getId());
        oi.setOrderinfoStatus("3");
        oi.setReceiveTime(new Date());
        ordersInfoMapper.updateByPrimaryKeySelective(oi);

        try {
            Map<String, String> map = new LinkedMap();
            map.put("childOrderNo", ordersInfo.getChildOrderNo());
            String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/order/updateOrderReceiveStatus", map, supplyApiConfig.getHeadsMap());
            log.info("===========/order/updateOrderReceiveStatus============{},{}", s, orderInfoId);
        } catch (Exception e) {
            log.info("======签收状态同步订单信息到供应链1失败======{}", e);
        }

        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(ordersInfo.getOrderId());
        List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
        boolean flag = true;
        for (OrdersInfo item : ordersInfos) {
            if (!"3".equals(item.getOrderinfoStatus())) {
                flag = false;
                break;
            }
        }
        // 修改订单主表的状态
        if (flag) {
            Orders orders = new Orders();
            orders.setId(ordersInfo.getOrderId());
            orders.setOrderStatus("3");
            ordersMapper.updateByPrimaryKeySelective(orders);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderResponse getOrderInfoById(Integer orderId, Integer userId, String city) {
        String sourcePlatform = TokenUtil.getSourcePlatform();
        OrderResponse response = new OrderResponse();
        // 订单主表信息
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        //更新用户地址,解决H5调小程序地址错误问题
        UsersAddress usersAddress = usersAddressMapper.selectByUserId(orders.getUserId());
        if (null != usersAddress) {
            usersAddress.setName(orders.getUserName());
            usersAddress.setTel(orders.getTel());
            usersAddress.setSort(1);
            usersAddress.setProvince(orders.getProvince());
            usersAddress.setCity(orders.getCity());
            usersAddress.setArea(orders.getArea());
            usersAddress.setAddress(orders.getAddress());
            usersAddress.setStatus((byte)1);
            usersAddress.setUpdateTime(new Date());
            usersAddressMapper.updateByPrimaryKey(usersAddress);
        } else {
            usersAddress = new UsersAddress();
            usersAddress.setUserId(userId);
            usersAddress.setName(orders.getUserName());
            usersAddress.setTel(orders.getTel());
            usersAddress.setSort(1);
            usersAddress.setProvince(orders.getProvince());
            usersAddress.setCity(orders.getCity());
            usersAddress.setArea(orders.getArea());
            usersAddress.setAddress(orders.getAddress());
            usersAddress.setStatus((byte)1);
            usersAddress.setCreateTime(new Date());
            usersAddressMapper.insert(usersAddress);
        }

        DefaultAddressDto address = usersClient.getDefaultAddress(orders.getUserId());
        OrdersInfoExample example = new OrdersInfoExample();
        example.createCriteria().andOrderIdEqualTo(orderId);
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(example);

        OrdersInfo ordersInfo = ordersInfoList.get(0);

        FreightTemplateResponse freightTemplateResponse = getFreightTemplateResponse(ordersInfo.getProductId());

        try{
            BigDecimal totalFreight =  calculateFreight(freightTemplateResponse,ordersInfo.getProductSum(),StringUtils.isBlank(city)?address.getCity():city,address.getProvince());
            //查询运费数据是否存在
            OrdersInfoFreightDto dto = ordersDao.selectFreightByChildOrderNo(ordersInfo.getChildOrderNo());
            log.info("查询运费数据是否存在：{}",JSONObject.toJSON(dto));
            if (null != dto) {
                //更新子订单运费
                ordersDao.updateFreight(totalFreight, ordersInfo.getChildOrderNo());
                //更新主订单支付金额
                orders.setTotalMoney(orders.getTotalMoney().subtract(dto.getFreight()).add(totalFreight));
                orders.setRealTotalMoney(orders.getRealTotalMoney().subtract(dto.getFreight()).add(totalFreight));
                ordersMapper.updateByPrimaryKeySelective(orders);
            } else {
                //新增运费数据
                createOrderInfoFreight(ordersInfo,orders,totalFreight,freightTemplateResponse.getId());
            }
            response.setFreight(totalFreight);
            response.setFreights(totalFreight);
        }catch (Exception e) {
            log.info("计算h5计算运费错误：",e.getMessage());
            response.setFreight(BigDecimal.ZERO);
            response.setFreights(BigDecimal.ZERO);
        }

        Orders ordersNew = ordersMapper.selectByPrimaryKey(orderId);

        response.setPayExpirationTime(getDate(orders.getCreateTime(), 1));
        response.setOrderId(orderId);
        response.setOrderNo(orders.getOrderNo());
        // 订单原总价格
        response.setTotalMoney(ordersNew.getTotalMoney());
        // 订单实付总价格
        response.setRealTotalMoney(ordersNew.getRealTotalMoney());
        response.setPaySource(orders.getPaySource());
        // 支付类型
        response.setPayTypeList(Arrays.asList(
                commonService.getSysConfigValue(SysConfigConstants.PAY_LIST)
                        .split(",")));
        // 收货地址
        if (StringUtils.isBlank(city)){
            response.setAddress(usersClient.getDefaultAddress(userId));
        }
        if (StringUtils.isNotBlank(sourcePlatform)) {
            response.setAddress(address);
            response.setAddressText(address != null ? address.getProvince() + address.getCity() + address.getArea() + address.getAddress() : "");
        }

        response.setCreateTime(orders.getCreateTime());

        //查询国外商品的数量
        Integer total = ordersMapper.findProducTypeByOrderId(orderId);
        if (total != null && total > 0) {
            response.setProductType(2);
            UsersRealName usersRealName = usersRealNameMapper.getByUserId(userId);
            response.setUsersRealName(usersRealName);
        } else {
            response.setProductType(1);
        }


        AtomicBoolean haveReturnRecord = new AtomicBoolean(false);
        // 订单详情信息

        response.setOrderInfoList(ordersInfoList.stream().map(item -> {
            OrderInfoResponse infoResponse = new OrderInfoResponse(item);
            ProductResponse productResponse = productService.queryProductById(item.getProductId());
            //如果是待收货,就返回收货时间
            if (null != item.getDeliveryTime()) {
                infoResponse.setCompleteTime(getDate(item.getDeliveryTime(), 24 * 7));
            }
            infoResponse.setStock(productResponse.getStock());
            infoResponse.setVolumeStr(productResponse.getVolumeStr());

            ReturnGoodsExample returnGoodsExample = new ReturnGoodsExample();
            returnGoodsExample.createCriteria().andOrdersInfoIdEqualTo(item.getId());
            returnGoodsExample.setOrderByClause("create_time desc");
            List<ReturnGoods> returnGoods = returnGoodsMapper.selectByExample(returnGoodsExample);
            infoResponse.setReturnFlag(0);
            if (!CollectionUtils.isEmpty(returnGoods)) {
                infoResponse.setReturnFlag(1);
                haveReturnRecord.set(true);
            }
            if (StringUtils.isEmpty(item.getOrderinfoStatus())) {
                infoResponse.setStatus(Integer.parseInt(orders.getOrderStatus()));
            } else {
                infoResponse.setStatus(Integer.parseInt(item.getOrderinfoStatus()));
            }
            infoResponse.setServiceNo(CollectionUtils.isEmpty(returnGoods) ? null : returnGoods.get(0).getServiceNo());
            return infoResponse;
        }).collect(Collectors.toList()));

        // ----------------------------------------------------计算各种优惠价格总和---------------------------------------------------------------------
        Map<String, Object> discountType = new HashMap<>();
        // 积分
        BigDecimal cashScoreActivityMax = new BigDecimal(0);           // 积分
        BigDecimal cashScoreActivityMin = new BigDecimal(0);           // 购买的积分
        BigDecimal cashScoreReducedPrice = new BigDecimal(0);           // 抵扣价格
        // 返积分
        BigDecimal returnScore = new BigDecimal(0);
        // 大额神券
        BigDecimal cashCouponReducedPrice = new BigDecimal(0);
        // 以旧换新
        BigDecimal oldForNewReducedPrice = new BigDecimal(0);
        //拼团价格
        BigDecimal groupBuyReducePrice = new BigDecimal(0);

        BigDecimal price = BigDecimal.ZERO;
        BigDecimal totalMoney = BigDecimal.ZERO;

        String activityType = "";
        for (OrdersInfo item : ordersInfoList) {
            if (null != item.getProductSum()) {
                price = price.add(item.getProductPrice().multiply(BigDecimal.valueOf(item.getProductSum())));
                totalMoney = totalMoney.add(item.getProductOprice().multiply(BigDecimal.valueOf(item.getProductSum())));
            } else {
                price = price.add(item.getProductPrice());
                totalMoney = totalMoney.add(item.getProductOprice());
            }

            // 只有 活动商品  + 不是直接购买  才累加优惠
            if (StringUtils.isNotBlank(item.getActivityType()) && item.getIsDirectbuy() != 1) {
                // 活动类型
                switch (item.getActivityType()) {
                    case "CASH_SCORE":
                        // 兑换积分
                        cashScoreActivityMax = cashScoreActivityMax.add(item.getActivityMax());
                        cashScoreActivityMin = cashScoreActivityMin.add(item.getActivityMin());
                        cashScoreReducedPrice = cashScoreReducedPrice.add(item.getProductOprice().subtract(item.getProductPrice()));
                        break;
                    case "GET_SCORE":
                    case "NEW_USER":
                        // 新人首单返积分、返积分 统一加积分
                        returnScore = returnScore.add(item.getActivityMax());
                        break;
                    case "CASH_COUPON":
                        cashCouponReducedPrice = cashCouponReducedPrice.add(item.getActivityMax());
                        break;
                    case "OLD_FOR_NEW":
                        // 以旧换新
                        oldForNewReducedPrice = oldForNewReducedPrice.add(item.getActivityMax());
                        break;
                    case "GROUP_WORK":
                        ProductGroupBuyInfo groupBuyInfo = yxProductGroupBuyInfoService.queryByProductId(item.getProductId());
                        groupBuyReducePrice = groupBuyReducePrice.add(item.getProductPrice().subtract(groupBuyInfo.getGroupPrice()));
                }
            }
            if (StringUtils.isNotEmpty(item.getActivityType())) {
                activityType = item.getActivityType();
            }
        }

        // 积分
        Map<String, Object> cashScore = new HashMap<>();
        cashScore.put("cashScoreActivityMax", cashScoreActivityMax.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScoreActivityMin", cashScoreActivityMin.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScorePrice", cashScoreReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        discountType.put("cashScore", cashScore);
        // 返积分
        discountType.put("returnScore", returnScore.setScale(2, BigDecimal.ROUND_UP));
        // 大额神券
        discountType.put("cashCouponPrice", cashCouponReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        // 以旧换新
        discountType.put("oldForNewPrice", oldForNewReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        // 拼团优惠价
        discountType.put("groupBuyReducePrice", groupBuyReducePrice.setScale(2, BigDecimal.ROUND_UP));
        discountType.put("activityType", activityType);

        // 平台立减
        BigDecimal platformPrice = orders.getTotalMoney()
                .subtract(cashScoreReducedPrice)                // 积分抵扣
                .subtract(cashCouponReducedPrice)               // 优惠券
                .subtract(oldForNewReducedPrice)                // 以旧换新
                .subtract(orders.getRealTotalMoney())           // 实际支付价格
                .setScale(2, BigDecimal.ROUND_UP);
        discountType.put("platformPrice", platformPrice);
        response.setDiscountType(discountType);
        response.setPayStatus(orders.getIsPay().intValue());
        response.setOrderStatus(orders.getOrderStatus());
        response.setPayTime(orders.getPayTime());
        response.setPayType(orders.getPayType());
        response.setReturnFlag(0);
        if (haveReturnRecord.get()) {
            response.setReturnFlag(1);
        }
        response.setProductPriceAndFreights(price.add(response.getFreights()));
        response.setTotalMoney(totalMoney);
        return response;
    }


    @Override
    public OrderResponse getOrderInfoByNo(String orderNo,Integer userId, String city){
        Orders orders = ordersMapper.selectByOrderNo(orderNo);
        Optional.ofNullable(orders).orElseThrow(() -> new ApiException("该订单不存在!"));
        return getOrderInfoById(orders.getId(),userId,city);
    }

    /**
     * 拆单需要用到这个方法
     *
     * @param orderId
     * @param userId
     * @return
     */
    public OrderResponse getOrderInfoById2(Integer orderId, Integer userId) {
        OrderResponse response = new OrderResponse();
        // 订单主表信息
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andOrderParentNoEqualTo(orders.getOrderParentNo());
        List<Orders> ordersList = ordersMapper.selectByExample(ordersExample);
        response.setOrderId(orders.getId());
        response.setOrderNo(orders.getOrderNo());
        response.setTotalMoney(ordersList.stream().map(Orders::getTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add));
        response.setRealTotalMoney(ordersList.stream().map(Orders::getRealTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add));


        // 订单原总价格
//        response.setTotalMoney(orders.getTotalMoney());
        // 订单实付总价格
//        response.setRealTotalMoney(orders.getRealTotalMoney());
        // 运费
        response.setFreight(new BigDecimal(0));
        response.setPaySource(orders.getPaySource());
        // 支付类型
        response.setPayTypeList(Arrays.asList(
                commonService.getSysConfigValue(SysConfigConstants.PAY_LIST)
                        .split(",")));
        // 收货地址
//        response.setAddress(usersClient.getDefaultAddress(userId));
        DefaultAddressDto addressDto = usersClient.getDefaultAddress(userId);
        response.setAddress(generateAddressInfoByOrder(orders, null == addressDto ? null : addressDto.getId()));
        response.setCreateTime(orders.getCreateTime());

        // 订单详情信息
        OrdersInfoExample example = new OrdersInfoExample();
//        example.createCriteria().andOrderIdEqualTo(orderId);
        example.createCriteria().andOrderIdIn(ordersList.stream().map(Orders::getId).collect(Collectors.toList()));
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(example);
        response.setOrderInfoList(ordersInfoList.stream().map(item -> {
            OrderInfoResponse infoResponse = new OrderInfoResponse(item);
            ProductResponse productResponse = productService.getProductById(item.getProductId(), "");
            //展示时不需要校验库存
//            if (Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.IS_STOCE_VERIFY)) > 0 && productResponse.getStock() <= 0) {
//                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
//            }
            infoResponse.setStock(productResponse.getStock());
            infoResponse.setVolumeStr(productResponse.getVolumeStr());

            ReturnGoodsExample returnGoodsExample = new ReturnGoodsExample();
            returnGoodsExample.createCriteria().andOrdersInfoIdEqualTo(item.getId());
            returnGoodsExample.setOrderByClause("create_time desc");
            List<ReturnGoods> returnGoods = returnGoodsMapper.selectByExample(returnGoodsExample);

            if (StringUtils.isEmpty(item.getOrderinfoStatus())) {
                infoResponse.setStatus(Integer.parseInt(orders.getOrderStatus()));
            } else {
                infoResponse.setStatus(Integer.parseInt(item.getOrderinfoStatus()));
            }
            infoResponse.setServiceNo(CollectionUtils.isEmpty(returnGoods) ? null : returnGoods.get(0).getServiceNo());
            return infoResponse;
        }).collect(Collectors.toList()));

        // ----------------------------------------------------计算各种优惠价格总和---------------------------------------------------------------------
        Map<String, Object> discountType = new HashMap<>();
        // 积分
        BigDecimal cashScoreActivityMax = new BigDecimal(0);           // 积分
        BigDecimal cashScoreActivityMin = new BigDecimal(0);           // 购买的积分
        BigDecimal cashScoreReducedPrice = new BigDecimal(0);           // 抵扣价格
        // 返积分
        BigDecimal returnScore = new BigDecimal(0);
        // 大额神券
        BigDecimal cashCouponReducedPrice = new BigDecimal(0);
        // 以旧换新
        BigDecimal oldForNewReducedPrice = new BigDecimal(0);
        //拼团价格
        BigDecimal groupBuyReducePrice = new BigDecimal(0);

        String activityType = "";
        for (OrdersInfo item : ordersInfoList) {
            // 只有 活动商品  + 不是直接购买  才累加优惠
            if (StringUtils.isNotBlank(item.getActivityType()) && item.getIsDirectbuy() != 1) {
                // 活动类型
                switch (item.getActivityType()) {
                    case "CASH_SCORE":
                        // 兑换积分
                        cashScoreActivityMax = cashScoreActivityMax.add(item.getActivityMax());
                        cashScoreActivityMin = cashScoreActivityMin.add(item.getActivityMin());
                        cashScoreReducedPrice = cashScoreReducedPrice.add(item.getProductOprice().subtract(item.getProductPrice()));
                        break;
                    case "GET_SCORE":
                    case "NEW_USER":
                        // 新人首单返积分、返积分 统一加积分
                        returnScore = returnScore.add(item.getActivityMax());
                        break;
                    case "CASH_COUPON":
                        cashCouponReducedPrice = cashCouponReducedPrice.add(item.getActivityMax());
                        break;
                    case "OLD_FOR_NEW":
                        // 以旧换新
                        oldForNewReducedPrice = oldForNewReducedPrice.add(item.getActivityMax());
                        break;
                    case "GROUP_WORK":
                        ProductGroupBuyInfo groupBuyInfo = yxProductGroupBuyInfoService.queryByProductId(item.getProductId());
                        groupBuyReducePrice = groupBuyReducePrice.add(item.getProductPrice().subtract(groupBuyInfo.getGroupPrice()));
                }
            }
            if (StringUtils.isNotEmpty(item.getActivityType())) {
                activityType = item.getActivityType();
            }
        }

        // 积分
        Map<String, Object> cashScore = new HashMap<>();
        cashScore.put("cashScoreActivityMax", cashScoreActivityMax.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScoreActivityMin", cashScoreActivityMin.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScorePrice", cashScoreReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        discountType.put("cashScore", cashScore);
        // 返积分
        discountType.put("returnScore", returnScore.setScale(2, BigDecimal.ROUND_UP));
        // 大额神券
        discountType.put("cashCouponPrice", cashCouponReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        // 以旧换新
        discountType.put("oldForNewPrice", oldForNewReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        // 拼团优惠价
        discountType.put("groupBuyReducePrice", groupBuyReducePrice.setScale(2, BigDecimal.ROUND_UP));
        discountType.put("activityType", activityType);

        // 平台立减
        BigDecimal platformPrice = orders.getTotalMoney()
                .subtract(cashScoreReducedPrice)                // 积分抵扣
                .subtract(cashCouponReducedPrice)               // 优惠券
                .subtract(oldForNewReducedPrice)                // 以旧换新
                .subtract(orders.getRealTotalMoney())           // 实际支付价格
                .setScale(2, BigDecimal.ROUND_UP);
        discountType.put("platformPrice", platformPrice);
        response.setDiscountType(discountType);
        response.setPayStatus(orders.getIsPay().intValue());
        response.setOrderStatus(orders.getOrderStatus());
        response.setPayTime(orders.getPayTime());
        response.setPayType(orders.getPayType());
        return response;
    }

    private DefaultAddressDto generateAddressInfoByOrder(Orders orders, Integer id) {
        DefaultAddressDto dto = new DefaultAddressDto();
        dto.setId(id);
        dto.setAddress(orders.getAddress());
        dto.setArea(orders.getArea());
        dto.setCity(orders.getCity());
        dto.setName(orders.getUserName());
        dto.setProvince(orders.getProvince());
        dto.setTel(orders.getUserPhone());
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderResponse getPaySuccessInfo(Integer orderId, UsersResponse usersResponse, Integer payOrderId) {
        OrderResponse response = new OrderResponse();
        Integer userId = usersResponse.getId();
        // 订单主表
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);

        if (!"pay_delivery".equals(orders.getPayType())) {// null == userId &&
            // 兼容h5
            OrdersPay ordersPay = null;
            if (null == payOrderId) {
                List<OrdersPay> ordersPayList = ordersDao.findOrderPayListByOrderId(orderId);
                if (!CollectionUtils.isEmpty(ordersPayList)) {
                    ordersPay = ordersPayList.get(0);
                }
            } else {
                ordersPay = ordersPayMapper.selectByPrimaryKey(payOrderId);
            }
            if (null == ordersPay) {
                return response;
            }
            response.setRealTotalMoney(ordersPay.getAmount());
            response.setPayStatus(Integer.valueOf(ordersPay.getPayType()));
            response.setCreateTime(ordersPay.getCreateTime());
            response.setPaySource("aliPay".equals(ordersPay.getTradeType()) ? "aliPay" : "wx");
            if (orders.getIsPay().equals(PayPayTypeEnums.SUCCEED.getType())) {
                response.setPayStatus(2);
            } else if ("wx".equals(response.getPaySource()) && 1 == realWxOrderQuerySwitch) {
                Map<String, String> map = null;
                try {
                    String key;
                    if(!ordersPay.getTradeType().startsWith("H5-")){
                        key = "H5-" + ordersPay.getTradeType();
                    }else {
                        key = ordersPay.getTradeType();
                    }
                    map = wxServiceMap.get(key).wxOrderQuery(ordersPay.getResOrderNo());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                log.info("订单查询结果：{}", JSONObject.toJSONString(map));
                if ("SUCCESS".equals(map.get("trade_state"))) {
                    response.setPayStatus(2);
                } else if ("USERPAYING".equals(map.get("trade_state"))) {
                    response.setPayStatus(1);
                } else {
                    response.setPayStatus(3);
                }
            } else if (ordersPay.getPayType().equals(PayPayTypeEnums.SUCCEED.getType())){
                response.setPayStatus(2);
            } else {
                response.setPayStatus(1);
            }
        }
        // 订单明细
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(orderId);
        List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
        List<OrderInfoResponse> orderInfoResponses = ordersInfos.stream()
                .map(item -> {
                            OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
                            BeanUtils.copyProperties(item, orderInfoResponse);
                            return orderInfoResponse;
                        }
                ).collect(Collectors.toList());


        // 地址信息
        response.setOrderId(orders.getId());
        response.setUserName(orders.getUserName());
        response.setTel(orders.getUserPhone());
        DefaultAddressDto defaultAddressDto = new DefaultAddressDto();
        if (null != userId) {
            // 兼容h5
            defaultAddressDto.setProvince(orders.getProvince());
            defaultAddressDto.setCity(orders.getCity());
            defaultAddressDto.setArea(orders.getArea());
        }
        defaultAddressDto.setName(orders.getUserName());
        defaultAddressDto.setTel(orders.getUserPhone());
        defaultAddressDto.setAddress(orders.getAddress());
        response.setAddress(defaultAddressDto);
        response.setAddressText(orders.getUserAddress());

        if (null != userId) {
            // 兼容h5
            // 是活动积分的 返回积分
            if (ActivityTypeEnums.CASH_SCORE.name().equals(ordersInfos.get(0).getActivityType())) {
                UsersDto usersDto = usersClient.getUsersInfo(userId);
                response.setScore(usersDto.getScore());
            } else {
                // 判断是否支付
                // 如果用户没有领取过 则返回红包金额
                OrdersRewardExample ordersRewardExample = new OrdersRewardExample();
                ordersRewardExample.createCriteria().andOrderIdEqualTo(orderId).andUsersIdEqualTo(userId);
                List<OrdersReward> ordersRewardList = ordersRewardMapper.selectByExample(ordersRewardExample);
                Boolean flag = CollectionUtils.isEmpty(ordersRewardList) || ordersRewardList.get(0).getReceiveFlag() == 0 ? true : false;
                // 领取的红包金额范围
                BigDecimal amount = null;
                if (flag) {
                    if (CollectionUtils.isEmpty(ordersRewardList)) {
                        try {
                            String amountRange = sysConfigUtil.getSysConfig(SysConfigConstants.COLLECTION_AMOUNT_RANGE);
                            String min = amountRange.split("-")[0];
                            String max = amountRange.split("-")[1];
                            float Max = Float.parseFloat(max), Min = Float.parseFloat(min);
                            BigDecimal bd = new BigDecimal(Math.random() * (Max - Min) + Min);
                            amount = bd.setScale(2, BigDecimal.ROUND_HALF_UP); // 保留2位小数并四舍五入
                        } catch (RuntimeException e) {
                            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.UNRECOGNIZED));
                        }
                        // 保存数据
                        OrdersReward ordersReward = new OrdersReward();
                        ordersReward.setOrderId(orderId);
                        ordersReward.setUsersId(userId);
                        ordersReward.setReceiveFlag(0);
                        ordersReward.setReceiveMoney(amount);
                        ordersRewardMapper.insert(ordersReward);
                    } else {
                        amount = ordersRewardList.get(0).getReceiveMoney();
                    }

                    response.setAmount(amount);
                    // 没有领取 0
                    response.setIsReceive((byte) 0);
                } else {
                    response.setAmount(amount);
                    // 有领取过
                    response.setIsReceive((byte) 1);
                }

            }
        }

        // 订单信息
        response.setOrderNo(orders.getOrderNo());
        response.setActivityType(orderInfoResponses.get(0).getActivityType());
        response.setOrderInfoList(orderInfoResponses);

        // 之前老版本返回的数据
        response.setRealTotalMoney(orders.getRealTotalMoney());
        response.setCreateTime(orders.getCreateTime());
        response.setPayType(orders.getPayType());

        // 返回积分
        return response;
    }


    @Override
    public OrderResponse getPaySuccessInfoByOrderNo(String orderNo, UsersResponse usersResponse,Integer payOrderId) {
        OrderResponse response = new OrderResponse();
        Integer userId = usersResponse.getId();
        // 订单主表
        Orders orders = ordersMapper.selectByOrderNo(orderNo);

        if (!"pay_delivery".equals(orders.getPayType())) {// null == userId &&
            // 兼容h5
            OrdersPay ordersPay = null;
            if (null == payOrderId) {
                List<OrdersPay> ordersPayList = ordersDao.findOrderPayListByOrderNo(orderNo);
                if (!CollectionUtils.isEmpty(ordersPayList)) {
                    ordersPay = ordersPayList.get(0);
                }
            } else {
                ordersPay = ordersPayMapper.selectByPrimaryKey(payOrderId);
            }
            if (null == ordersPay) {
                return response;
            }
            response.setRealTotalMoney(ordersPay.getAmount());
            response.setPayStatus(Integer.valueOf(ordersPay.getPayType()));
            response.setCreateTime(ordersPay.getCreateTime());
            response.setPaySource("aliPay".equals(ordersPay.getTradeType()) ? "aliPay" : "wx");
            if (orders.getIsPay().equals(1)) {
                response.setPayStatus(2);
            } else if ("wx".equals(response.getPaySource()) && 1 == realWxOrderQuerySwitch) {
                Map<String, String> map = null;
                try {
                    String key;
                    if(!ordersPay.getTradeType().startsWith("H5-")){
                        key = "H5-" + ordersPay.getTradeType();
                    }else {
                        key = ordersPay.getTradeType();
                    }
                    map = wxServiceMap.get(key).wxOrderQuery(ordersPay.getResOrderNo());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                log.info("订单查询结果：{}", JSONObject.toJSONString(map));
                if ("SUCCESS".equals(map.get("trade_state"))) {
                    response.setPayStatus(2);
                } else if ("USERPAYING".equals(map.get("trade_state"))) {
                    response.setPayStatus(1);
                } else {
                    response.setPayStatus(3);
                }

            } else if (ordersPay.getPayType().equals(PayPayTypeEnums.SUCCEED.getType())){
                response.setPayStatus(2);
            } else {
                response.setPayStatus(1);
            }
        }
        // 订单明细
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(orders.getId());
        List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
        List<OrderInfoResponse> orderInfoResponses = ordersInfos.stream()
                .map(item -> {
                            OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
                            BeanUtils.copyProperties(item, orderInfoResponse);
                            return orderInfoResponse;
                        }
                ).collect(Collectors.toList());


        // 地址信息
        response.setOrderId(orders.getId());
        response.setUserName(orders.getUserName());
        response.setTel(orders.getUserPhone());
        DefaultAddressDto defaultAddressDto = new DefaultAddressDto();
        if (null != userId) {
            // 兼容h5
            defaultAddressDto.setProvince(orders.getProvince());
            defaultAddressDto.setCity(orders.getCity());
            defaultAddressDto.setArea(orders.getArea());
        }
        defaultAddressDto.setName(orders.getUserName());
        defaultAddressDto.setTel(orders.getUserPhone());
        defaultAddressDto.setAddress(orders.getAddress());
        response.setAddress(defaultAddressDto);
        response.setAddressText(orders.getUserAddress());

        if (null != userId) {
            // 兼容h5
            // 是活动积分的 返回积分
            if (ActivityTypeEnums.CASH_SCORE.name().equals(ordersInfos.get(0).getActivityType())) {
                UsersDto usersDto = usersClient.getUsersInfo(userId);
                response.setScore(usersDto.getScore());
            } else {
                // 判断是否支付
                // 如果用户没有领取过 则返回红包金额
                OrdersRewardExample ordersRewardExample = new OrdersRewardExample();
                ordersRewardExample.createCriteria().andOrderIdEqualTo(orders.getId()).andUsersIdEqualTo(userId);
                List<OrdersReward> ordersRewardList = ordersRewardMapper.selectByExample(ordersRewardExample);
                Boolean flag = CollectionUtils.isEmpty(ordersRewardList) || ordersRewardList.get(0).getReceiveFlag() == 0 ? true : false;
                // 领取的红包金额范围
                BigDecimal amount = null;
                if (flag) {
                    if (CollectionUtils.isEmpty(ordersRewardList)) {
                        try {
                            String amountRange = sysConfigUtil.getSysConfig(SysConfigConstants.COLLECTION_AMOUNT_RANGE);
                            String min = amountRange.split("-")[0];
                            String max = amountRange.split("-")[1];
                            float Max = Float.parseFloat(max), Min = Float.parseFloat(min);
                            BigDecimal bd = new BigDecimal(Math.random() * (Max - Min) + Min);
                            amount = bd.setScale(2, BigDecimal.ROUND_HALF_UP); // 保留2位小数并四舍五入
                        } catch (RuntimeException e) {
                            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.UNRECOGNIZED));
                        }
                        // 保存数据
                        OrdersReward ordersReward = new OrdersReward();
                        ordersReward.setOrderId(orders.getId());
                        ordersReward.setUsersId(userId);
                        ordersReward.setReceiveFlag(0);
                        ordersReward.setReceiveMoney(amount);
                        ordersRewardMapper.insert(ordersReward);
                    } else {
                        amount = ordersRewardList.get(0).getReceiveMoney();
                    }

                    response.setAmount(amount);
                    // 没有领取 0
                    response.setIsReceive((byte) 0);
                } else {
                    response.setAmount(amount);
                    // 有领取过
                    response.setIsReceive((byte) 1);
                }

            }
        }

        // 订单信息
        response.setOrderNo(orders.getOrderNo());
        response.setActivityType(orderInfoResponses.get(0).getActivityType());
        response.setOrderInfoList(orderInfoResponses);

        // 之前老版本返回的数据
        response.setRealTotalMoney(orders.getRealTotalMoney());
        response.setCreateTime(orders.getCreateTime());
        response.setPayType(orders.getPayType());

        // 返回积分
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receiveReward(Integer orderId, Integer userId) {
        // 查询该订单的奖励金额
        OrdersRewardExample ordersRewardExample = new OrdersRewardExample();
        ordersRewardExample.createCriteria().andOrderIdEqualTo(orderId).andUsersIdEqualTo(userId);
        List<OrdersReward> ordersRewardList = ordersRewardMapper.selectByExample(ordersRewardExample);
        if (CollectionUtils.isEmpty(ordersRewardList) && ordersRewardList.get(0).getReceiveFlag() == 1) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.CANNOT_REPEAT_DRAW));
        }
        BigDecimal receiveMoney = ordersRewardList.get(0).getReceiveMoney();

//        // 添加红包流水
//        usersClient.insetUsersBalanceRecord(userId, receiveMoney);

//        // 改变用户的余额 跟总余额
//        usersClient.updateMoney(userId, receiveMoney);

        OrdersReward ordersReward = new OrdersReward();
        ordersReward.setReceiveFlag(1);
        ordersReward.setReceiveTime(new Date());
        ordersRewardMapper.updateByExampleSelective(ordersReward, ordersRewardExample);
    }

    @Override
    public void updateOrdersUserInfo(OrdersUserInfoRequest ordersUserInfoRequest) {
        Orders orders = ordersMapper.selectByPrimaryKey(ordersUserInfoRequest.getOrderId());
        orders.setId(ordersUserInfoRequest.getOrderId());
        orders.setUserName(ordersUserInfoRequest.getName());
        orders.setUserPhone(ordersUserInfoRequest.getTel());
        String userAddress = ordersUserInfoRequest.getProvince()
                + ordersUserInfoRequest.getCity()
                + ordersUserInfoRequest.getArea()
                + ordersUserInfoRequest.getAddress();
        orders.setUserAddress(userAddress);
        orders.setProvince(ordersUserInfoRequest.getProvince());
        orders.setCity(ordersUserInfoRequest.getCity());
        orders.setArea(ordersUserInfoRequest.getArea());
        orders.setAddress(ordersUserInfoRequest.getAddress());
        ordersMapper.updateByPrimaryKeySelective(orders);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String wxAppletPayBack(String resXml,String type,String tradeType) {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(CompanyConstant.PLATFORM, type, tradeType);
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);
        WXPay wxpay = new WXPay(myWxConfig);
        return this.handleOrderBack(wxpay, resXml, type);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String handleOrderBack(final WXPay wxpay, String resXml, String type) {
        String xmlBack = "";
        Map<String, String> notifyMap = null;
        try {
            notifyMap = WXPayUtil.xmlToMap(resXml);         // 调用官方SDK转换成map类型数据
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//验证签名是否有效，有效则进一步处理

                String returnCode = notifyMap.get("return_code");//状态
                String outTradeNo = notifyMap.get("out_trade_no");//商户订单号
                if (returnCode.equals("SUCCESS")) {
                    if (outTradeNo != null) {
                        // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户的订单状态从退款改成支付成功
                        // 注意特殊情况：微信服务端同样的通知可能会多次发送给商户系统，所以数据持久化之前需要检查是否已经处理过了，处理了直接返回成功标志
                        // 业务数据持久化
                        log.info("===type==={}", type);
                        if ("H5".equals(type)) {
                            this.updateH5OrderPay(notifyMap);
                        } else {
                            this.updateOrderPay(notifyMap);
                        }
                        log.info("微信手机支付回调成功订单号:{}", outTradeNo);
                        xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                        //暂时注释试试 防止用户未点支付成功页面的完成
                        String orderNo = null;
                        Orders orders = null;
                        try {
                            OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(outTradeNo);
                            orderNo = pay.getOrderNo();
                            orders = ordersDao.queryOrdersByOrderNo(orderNo);
                            subStock(orders.getId());
                        } catch (Exception e) {
                            log.info("===支付完成后subStock异常==={}", e);
                        }
                        if (orderPushSwitch) {
                            try {
                                log.info("上传供应链7============{}", orders.getId());
                                ordersUpload(orders.getId(),null);
                            } catch (Exception e) {
                                log.error("上传供应链7失败============{}", e);
                            }
                        }
                    } else {
                        log.info("微信手机支付回调失败订单号:{}", outTradeNo);
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }

                }
                return xmlBack;
            } else {
                // 签名错误，如果数据里没有sign字段，也认为是签名错误
                //失败的数据要不要存储？
                log.error("手机支付回调通知签名错误");
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return xmlBack;
            }
        } catch (Exception e) {
            log.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }

    /**
     * 赠送测评佣金
     *
     * @param orderNo
     */
    private void giveBrokerageByDynamic(String orderNo) {
        if (StringUtils.isEmpty(orderNo)) {
            return;
        }
        Orders orders = ordersDao.queryOrdersByOrderNo(orderNo);
        if (null == orders) {
            return;
        }
        Integer dynamicId = orders.getDynamicId();
        if (null == dynamicId) {
            return;
        }
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(dynamicId);
        if (dynamic == null) {
            return;
        }
        if (null == dynamic.getIsReason()) {
            dynamic.setIsReason((byte) 1);
        }
        if (0 == dynamic.getIsReason() || 1 != dynamic.getStatus()) {
            return;
        }
        if (ActivityTypeEnums.ZERO_EVALUATION.name().equals(dynamic.getActivityType())) {
            return;
        }
        BigDecimal productPrice = dynamic.getProdcutPrice();//商品售价
        BigDecimal brokerage = productPrice.multiply(new BigDecimal(brokerageRatio)).setScale(4, RoundingMode.HALF_UP).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
        usersClient.addBalance(brokerage, dynamic.getUserId(), UserBalanceSourceEnums.EVALUATION_COMMISSION.name());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String handlePhoneOrderBack(final WXPay wxpay, String resXml, String type) {
        String xmlBack = "";
        Map<String, String> notifyMap = null;
        try {
            notifyMap = WXPayUtil.xmlToMap(resXml);         // 调用官方SDK转换成map类型数据
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//验证签名是否有效，有效则进一步处理

                String returnCode = notifyMap.get("return_code");//状态
                String outTradeNo = notifyMap.get("out_trade_no");//商户订单号
                if (returnCode.equals("SUCCESS")) {
                    if (outTradeNo != null) {
                        // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户的订单状态从退款改成支付成功
                        // 注意特殊情况：微信服务端同样的通知可能会多次发送给商户系统，所以数据持久化之前需要检查是否已经处理过了，处理了直接返回成功标志
                        // 业务数据持久化
                        log.info("===微信支付回调，开始处理业务==={}", notifyMap);
                        this.updateH5PhoneOrderPay(notifyMap);
                        log.info("微信手机支付回调成功订单号:{}", outTradeNo);
                        xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    } else {
                        log.info("微信手机支付回调失败订单号:{}", outTradeNo);
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }

                }
                return xmlBack;
            } else {
                // 签名错误，如果数据里没有sign字段，也认为是签名错误
                //失败的数据要不要存储？
                log.error("手机支付回调通知签名错误");
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return xmlBack;
            }
        } catch (Exception e) {
            log.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }

    @Override
    public Integer getOrdersInfoCount(Integer userId) {
        return ordersDao.getOrdersInfoCount(userId);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderResponse anewBuy(Integer orderId, Integer userId, String channel) {
        // 更新订单
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        // 判断订单是否是活动
        OrdersInfoExample example = new OrdersInfoExample();
        example.createCriteria()
                .andOrderIdEqualTo(orderId);
        Integer isStoceVerify = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.IS_STOCE_VERIFY));
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(example);
        BigDecimal realTotalMoney = new BigDecimal(0);
        BigDecimal totalMoney = new BigDecimal(0);

        // 新增订单
        orders = this.saveOrders(orders.getUserId(), orders.getTel(),
                orders.getTotalMoney(), orders.getRealTotalMoney(), orders.getOrderSource(), channel, 0);

        for (OrdersInfo ordersInfo : ordersInfoList) {
            // 普通商品
            ProductSpecResponse response = productService.getProductSpecInfoById(ordersInfo.getProductSpecId());
            // 校验库存
            if (isStoceVerify.intValue() == 1) {
                if (response.getStock() <= 0) {
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.COMMODITY_NOT_STOCK));
                }
            }
            ProductResponse product = productService.getProductById(response.getProductId(), "");
            // 如果直接购买则取现价
            if (ordersInfo.getIsDirectbuy() != null && ordersInfo.getIsDirectbuy() == 1) {
                response.setPrice(product.getCurPrice());
            }
            realTotalMoney = realTotalMoney.add(response.getPrice());
            totalMoney = totalMoney.add(product.getOriginalPrice());
            this.saveOrdersInfo(orders.getId(), product.getId(), product.getProductName(), product.getProductImg(),
                    response.getPrice(), product.getOriginalPrice(), product.getWarehouse(), product.getWarehouseName(),
                    product.getWarehouseRule(), ordersInfo.getSpecialId(), response.getSkuSpec(), product.getBankerId(), response.getId(),
                    product.getActivityType(), null, product.getActivityMax(), product.getActivityMin(), product.getDescr(),
                    ordersInfo.getIsDirectbuy(), ordersInfo.getPageSource(), null, product.getProductType(), 0,
                    response.getCostPrice(), response.getThreeSkuId(), 1, "",null);
            // todo 重新购买只有一件?
        }
        orders.setGoodsMoney(totalMoney.setScale(2));
        orders.setTotalMoney(totalMoney.setScale(2));
        orders.setRealTotalMoney(realTotalMoney.setScale(2));
        orders.setOrderStatus(OrderStatusEnums.OBLIGATION.getValue());
        orders.setCreateTime(new Date());
        ordersMapper.updateByPrimaryKeySelective(orders);
        return this.getOrderInfoById(orders.getId(), userId, null);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String wxAppPayBack(String resXml) {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(CompanyConstant.PLATFORM, WxAppServiceImpl.TYPE, WxAppServiceImpl.TRADE_TYPE);
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);
        WXPay wxpay = new WXPay(myWxConfig);
        return this.handleOrderBack(wxpay, resXml, WxAppServiceImpl.TYPE);
    }


    @Override
    public String wxH5PayBack(String resXml) {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(CompanyConstant.PLATFORM, WxH5JsApiServiceImpl.TYPE, WxAppJsApiServiceImpl.TRADE_TYPE);
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);
        WXPay wxpay = new WXPay(myWxConfig);
        return this.handleOrderBack(wxpay, resXml, WxH5JsApiServiceImpl.TYPE);
    }

    @Override
    public String wxH5PhonePayBack(String resXml) {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(CompanyConstant.PLATFORM, WxH5JsApiServiceImpl.TYPE, "PHONE_CHARGES");
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);
        WXPay wxpay = new WXPay(myWxConfig);
        return this.handlePhoneOrderBack(wxpay, resXml, WxH5JsApiServiceImpl.TYPE);
    }

    @Override
    public Boolean phoneBillComplete(Integer orderId) {
        PhoneRecharge phoneRecharge = phoneRechargeMapper.selectByPrimaryKey(orderId);
        if (phoneRecharge.getUuid().equals(TokenUtil.getToken())) {
            try {
                Map<String, String> resMap = wxServiceMap.get("H5-ISV-MWEB").wxPhoneChargesQuery(phoneRecharge.getOrderNo());
//                Map<String, String> resMap = this.wxOrderQuery(phoneRecharge.getOrderNo());
                log.info("订单查询结果：{}", JSONObject.toJSONString(resMap));
                if ("SUCCESS".equals(resMap.get("return_code"))) {
                    if ("SUCCESS".equals(resMap.get("result_code"))) {
                        // 成功
                        if ("SUCCESS".equals(resMap.get("trade_state"))) {
                            return true;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            // 修改订单状态 为异常
            PhoneRecharge data = new PhoneRecharge();
            data.setId(orderId);
            data.setErrorStatus(1);
            phoneRechargeMapper.updateByPrimaryKeySelective(data);
        }
        return false;
    }

    private Map<String, String> wxOrderQuery(String resOrderNo) throws Exception {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(CompanyConstant.PLATFORM, "H5", "PHONE_CHARGES");
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);

        Map<String, String> data = new HashMap<>();
        data.put("appid", payConfig.getAppid());
        WXPay wxpay = new WXPay(myWxConfig, WXPayConstants.SignType.MD5);
        data.put("mch_id", payConfig.getMchId());
        data.put("out_trade_no", resOrderNo);
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        data.put("sign", WXPayUtil.generateSignature(data, payConfig.getWxKey(),
                WXPayConstants.SignType.MD5));
        log.info("微信H5支付状态查询请求 订单号：{},query: {}", resOrderNo, JSONObject.toJSONString(data));
        //使用官方API请求预付订单
        Map<String, String> response = wxpay.orderQuery(data);
        log.info("微信H5支付状态查询响应 订单号：{},response: {}", resOrderNo, JSONObject.toJSONString(response));
        return response;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderPay(Map<String, String> map) {
        log.info("微信支付处理订单请求数据：{}", JSONObject.toJSONString(map));
        // 查询订单是否是处理中
        String resOrderNo = map.get("out_trade_no");
        OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(resOrderNo);
        log.info("===out_trade_no:{}, pay:{}", resOrderNo, JSONObject.toJSONString(pay));
        if (null == pay || (pay.getPayType().byteValue() != PayPayTypeEnums.BEING_PROCESSED.getType() && PayPayTypeEnums.FAIL.getType() != pay.getPayType().byteValue())) {
            log.info("===updateOrderPay return:{}", resOrderNo);
            return;
        }
        log.info("updateOrderPay.result_code:{}", resOrderNo);
        if ("SUCCESS".equals(map.get("trade_state")) || "SUCCESS".equals(map.get("result_code"))) {
            log.info("=====11111111111====");
            // 更新支付订单信息
            pay.setIsSubscribe(map.get("is_subscribe"));
            pay.setTradeType(map.get("trade_type"));
            pay.setBankType(map.get("bank_type"));
            if (null != map.get("total_fee")) {
                pay.setTotalFee(Integer.valueOf(map.get("total_fee")));
            } else {
                log.info("===totalFee is null==={}", resOrderNo);
                Integer totalFee = 0;
                if (null != pay.getAmount()) {
                    BigDecimal big_total_fee = pay.getAmount().multiply(new BigDecimal(100));
                    totalFee = big_total_fee.intValue();
                }
                pay.setTotalFee(totalFee);
            }
            pay.setResText(JSONObject.toJSONString(map));
            pay.setPayTime(map.get("time_end"));
            pay.setPayType(PayPayTypeEnums.SUCCEED.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
            log.info("=======2222222========");
            // 更新订单信息
            Orders orders = new Orders();
            orders.setPayType(OrderPayTypeEnums.online_pay.name());
            orders.setPaySource(OrderPaySource.wx.name());
            orders.setIsPay(IsPayConstant.YES);
            orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
            orders.setPayTime(new Date());
            orders.setTradeNo(pay.getResOrderNo());
            OrdersExample example = new OrdersExample();
            example.createCriteria()
                    .andOrderNoEqualTo(pay.getOrderNo());
            ordersMapper.updateByExampleSelective(orders, example);


            // 获取订单信息
            Orders order = ordersDao.queryOrdersByOrderNo(pay.getOrderNo());
            log.info("===order info==={}", order);

            // 获取订单明细
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(order.getId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            ordersInfoList.stream()
                    .forEach(item -> {
                        String tokenUser = redisService.get(order.getH5Token());

                        // 修改订单详情状态
                        OrdersInfo ordersInfo = new OrdersInfo();
                        ordersInfo.setId(item.getId());
                        ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                        ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                        try {
                            // 商品 减库存 加销量 店家加销量
                            productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(),tokenUser, item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), order.getUserId());
                        } catch (Exception e) {
                            log.error(GlobalExceptionHandler.getExceptionToString(e));
                            log.error("减库存发生异常 订单id :{}", item.getId());
                        }

                    });
            try {
                subStock(order.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (orderPushSwitch) {
                try {
                    log.info("上传供应链8============{}", order.getId());
                    ordersUpload(order.getId(),null);
                } catch (Exception e) {
                    log.error("上传供应链8失败============{}", e);
                }
            }

        } else {
            // 更新支付订单信息
            pay.setIsSubscribe(map.get("is_subscribe"));
            pay.setTradeType(map.get("trade_type"));
            pay.setBankType(map.get("bank_type"));
            if (null != map.get("total_fee")) {
                pay.setTotalFee(Integer.valueOf(map.get("total_fee")));
            } else {
                log.info("===total_fee is null==={}", resOrderNo);
                Integer totalFee = 0;
                if (null != pay.getAmount()) {
                    BigDecimal big_total_fee = pay.getAmount().multiply(new BigDecimal(100));
                    totalFee = big_total_fee.intValue();
                }
                pay.setTotalFee(totalFee);
            }
            pay.setResText(JSONObject.toJSONString(map));
            pay.setPayTime(map.get("time_end"));
            pay.setPayType(PayPayTypeEnums.FAIL.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
        }
        log.info("处理订单完毕-");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateH5OrderPay(Map<String, String> map) {
        log.info("===updateH5OrderPay==={}", map);
        // 查询订单是否是处理中
        String resOrderNo = map.get("out_trade_no");
        OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(resOrderNo);
        if (null == pay || (!pay.getPayType().equals(PayPayTypeEnums.BEING_PROCESSED.getType()) && PayPayTypeEnums.FAIL.getType() != pay.getPayType().byteValue())) {
            return;
        }
//        log.info("" + map.get("result_code").equals("SUCCESS"));
        if ("SUCCESS".equals(map.get("trade_state")) || "SUCCESS".equals(map.get("result_code"))) {
//        if (map.get("result_code").equals("SUCCESS")) {
            // 更新支付订单信息
            pay.setIsSubscribe(map.get("is_subscribe"));
            pay.setTradeType(map.get("trade_type"));
            pay.setBankType(map.get("bank_type"));
            if (null != map.get("total_fee")) {
                pay.setTotalFee(Integer.valueOf(map.get("total_fee")));
            } else {
                log.info("===total_fee is null==={}", resOrderNo);
                Integer totalFee = 0;
                if (null != pay.getAmount()) {
                    BigDecimal big_total_fee = pay.getAmount().multiply(new BigDecimal(100));
                    totalFee = big_total_fee.intValue();
                }
                pay.setTotalFee(totalFee);
            }
            pay.setResText(JSONObject.toJSONString(map));
            pay.setPayTime(map.get("time_end"));
            pay.setPayType(PayPayTypeEnums.SUCCEED.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
            // 更新订单信息
            Orders orders = new Orders();
            orders.setPayType(OrderPayTypeEnums.online_pay.name());
            orders.setPaySource(OrderPaySource.wx.name());
            orders.setIsPay(IsPayConstant.YES);
            orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
            orders.setPayTime(new Date());
            orders.setTradeNo(pay.getResOrderNo());
            OrdersExample example = new OrdersExample();
            example.createCriteria().andOrderNoEqualTo(pay.getOrderNo());
            ordersMapper.updateByExampleSelective(orders, example);

            // 获取订单信息
            Orders order = ordersDao.queryOrdersByOrderNo(pay.getOrderNo());
            // 获取订单明细
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria()
                    .andOrderIdEqualTo(order.getId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            AtomicInteger activityType = new AtomicInteger(0);
            ordersInfoList.stream()
                    .forEach(item -> {
                        String tokenUser = redisService.get(order.getH5Token());

                        // 修改订单详情状态
                        OrdersInfo ordersInfo = new OrdersInfo();
                        ordersInfo.setId(item.getId());
                        ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                        ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                        try {
                            // 商品 减库存 加销量 店家加销量
                            productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(), tokenUser, item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), order.getUserId());
                        } catch (Exception e) {
                            log.error("程序出现异常：e:{}", GlobalExceptionHandler.getExceptionToString(e));
                            log.error("减库存发生异常 订单id :{}", item.getId());
                        }

                        switch (item.getActivityType()) {
                            case "RETURN_COUPON":
                                this.addReturnCoupon(item.getActivityMax(), RedisConstants.RETURN_COUPON + order.getH5Token());//记录用户返现红包金额
                                break;
                            case "WALLET_DEDUCT":
                                subH5Wallet(item.getActivityMax(), order.getH5Token());
                                break;
                            case "GET_SCORE":
                                addH5Wallet(item.getActivityMax(), order.getH5Token());
                                break;
                            case "LIVING_CENTER":
                                try {
                                    activityType.set(1);
                                } catch (Exception e) {
                                }
                                break;
                            case "CASH_COUPON":
                                this.addUsedActivityMax(item.getActivityMax(), RedisConstants.RETURN_COUPON + order.getH5Token());//记录用户使用红包金额
                                updateCouponRecord(order.getH5Token(), item.getProductId());
                                break;
                            case "MEMBER_SUBSIDY":
                            case "OLD_FOR_NEW":
                                String key = RedisConstants.SUBSIDYKEY + order.getH5Token();
                                log.info("===微信支付回调，获取当前platformData={}=,orderSource={}==", TokenUtil.getPlatformData(), orders.getOrderSource());
                                String subsidyObj = "";
                                try {
                                    subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                                } catch (Exception e) {
                                    log.info("===redis get key is err===");
                                }
//                                if ("APP".equals(TokenUtil.getPlatformData().toUpperCase())) {
                                this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, order.getH5Token(), orders.getUserId());
//                                } else {
                                if (StringUtils.isNotEmpty(subsidyObj)) {
                                    redisService.delete(key, item.getProductId().toString());
                                }
                                this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, order.getH5Token());
//                                }
                                break;
                        }

                    });
            // 发送短信
            try {
//            AliyunSmsUtil.sendSms(telephone,1,"");
//                log.info("===cmpp下单成功发送短信手机号==={}", order.getUserPhone());
//                SmsDto smsDto = new SmsDto();
//                smsDto.setPhone(order.getUserPhone());
//                smsDto.setType(2);
//                smsDto.setOrderSource(order.getOrderSource());
//                String productName = ordersInfoList.get(0).getProductName();
//                if (ordersInfoList.size() > 1) {
//                    if (productName.length() > 12) {
//                        productName = productName.substring(0, 12) + "等";
//                    } else {
//                        productName = productName + "等";
//                    }
//                } else {
//                    if (productName.length() > 12) {
//                        productName = productName.substring(0, 12) + "等";
//                    }
//                }
//                smsDto.setCode(productName);
//                smsDto.setOrderSource(order.getOrderSource());
//                smsDto.setChannel(order.getChannel());
//                rabbitTemplate.convertAndSend(QueueConstants.SMS_QUEUE, smsDto);
                sendOrderPaySucSms(order, ordersInfoList.get(0), ordersInfoList.size());
                if (1 == activityType.get() && order.getRealTotalMoney().compareTo(new BigDecimal(50)) > 0) {
                    addH5Wallet(order.getRealTotalMoney(), order.getH5Token());
                }
            } catch (Exception e) {
            }
            List<Orders> ordersList = ordersMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(ordersList)) {
                subStock(ordersList.get(0).getId());
                if (orderPushSwitch) {
                    try {
                        log.info("上传供应链9============{}", ordersList.get(0).getId());
                        ordersUpload(ordersList.get(0).getId(),null);
                    } catch (Exception e) {
                        log.error("上传供应链9失败============{}", e);
                    }
                }
            }

        } else {
            // 更新支付订单信息
            pay.setIsSubscribe(map.get("is_subscribe"));
            pay.setTradeType(map.get("trade_type"));
            pay.setBankType(map.get("bank_type"));
            if (null != map.get("total_fee")) {
                pay.setTotalFee(Integer.valueOf(map.get("total_fee")));
            } else {
                log.info("===total_fee is null==={}", resOrderNo);
                Integer totalFee = 0;
                if (null != pay.getAmount()) {
                    BigDecimal big_total_fee = pay.getAmount().multiply(new BigDecimal(100));
                    totalFee = big_total_fee.intValue();
                }
                pay.setTotalFee(totalFee);
            }
            pay.setResText(JSONObject.toJSONString(map));
            pay.setPayTime(map.get("time_end"));
            pay.setPayType(PayPayTypeEnums.FAIL.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
        }

    }

    private void updateCouponRecord(String token, Integer productId) {
        try {
            couponRecordsDao.updateUsed(productId, token);
        } catch (Exception e) {
            log.error("更新红包记录错误", e);
        }
    }

    //返积分
    private void addH5Score(Integer addScore, String h5token) {
        try {
            String usesInfo = redisService.get(h5token);
            UsersResponse usersResponse = JSONObject.parseObject(usesInfo, UsersResponse.class);
            usersResponse.setScore(usersResponse.getScore() + addScore);
            redisService.set(usersResponse.getToken(), JSONObject.toJSONString(usersResponse));
            redisService.expire(usersResponse.getToken(), TokenConstants.EXPIRE_SECONDS);
        } catch (Exception e) {
            log.error("加积分异常：h5token={}", h5token);
        }

    }

    private void subH5Wallet(BigDecimal ordersInfoActivityMax, String h5token) {
        String redisKey = RedisConstants.WALLET_DEDUCT_H5 + h5token;
        String dtoStr = redisService.get(redisKey);
        WalletDeductDto walletDeductDto = null;
        if (StringUtils.isNotEmpty(dtoStr)) {
            walletDeductDto = JSONObject.parseObject(dtoStr, WalletDeductDto.class);
        } else {
            walletDeductDto = new WalletDeductDto();
            walletDeductDto.setAmount(BigDecimal.ZERO);
        }
        ordersInfoActivityMax = Optional.ofNullable(ordersInfoActivityMax)
                .orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);
        if (ordersInfoActivityMax.compareTo(walletDeductDto.getAmount()) > 0) {
            walletDeductDto.setAmount(BigDecimal.ZERO);
        } else {
            walletDeductDto.setAmount(walletDeductDto.getAmount().subtract(ordersInfoActivityMax));
        }

        redisService.set(redisKey, JSONObject.toJSONString(walletDeductDto));
        redisService.expire(redisKey, 60 * 60 * 24 * 30);
    }

    private void addH5Wallet(BigDecimal ordersInfoActivityMax, String h5token) {
        String redisKey = RedisConstants.WALLET_DEDUCT_H5 + h5token;
        String dtoStr = redisService.get(redisKey);
        WalletDeductDto walletDeductDto = null;
        if (StringUtils.isNotEmpty(dtoStr)) {
            walletDeductDto = JSONObject.parseObject(dtoStr, WalletDeductDto.class);
        } else {
            walletDeductDto = new WalletDeductDto();
            walletDeductDto.setAmount(BigDecimal.ZERO);
        }
        ordersInfoActivityMax = Optional.ofNullable(ordersInfoActivityMax)
                .orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);
        walletDeductDto.setAmount(ordersInfoActivityMax.add(walletDeductDto.getAmount()));
        redisService.set(redisKey, JSONObject.toJSONString(walletDeductDto));
        redisService.expire(redisKey, 60 * 60 * 24 * 30);
    }

    private void addReturnCoupon(BigDecimal ordersInfoActivityMax, String key) {
        ReturnCouponResponse returnCouponResponse = new ReturnCouponResponse();

        if (StringUtils.isNotEmpty(redisService.get(key))) {// 记录用户返现红包金额
            returnCouponResponse = JSONObject.parseObject(redisService.get(key), ReturnCouponResponse.class);
        } else {
            returnCouponResponse.setUsedActivityMax(BigDecimal.ZERO);
        }
        // 商品红包
        ordersInfoActivityMax = Optional.ofNullable(ordersInfoActivityMax)
                .orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);
        // 累计返现红包
        BigDecimal totalReturnCoupon = Optional.ofNullable(returnCouponResponse.getTotalReturnCoupon())
                .orElse(BigDecimal.ZERO)
                .setScale(2, BigDecimal.ROUND_HALF_UP);
        // 用户红包
        BigDecimal userActivityMax = Optional.ofNullable(returnCouponResponse.getActivityMax())
                .orElse(BigDecimal.valueOf(680))
                .setScale(2, BigDecimal.ROUND_HALF_UP);

        // 累计返现红包 += 商品红包
        totalReturnCoupon = totalReturnCoupon
                .add(ordersInfoActivityMax)
                .setScale(2, BigDecimal.ROUND_HALF_UP);
        // 返现红包 += 用户的红包
        userActivityMax = ordersInfoActivityMax
                .add(userActivityMax)
                .setScale(2, BigDecimal.ROUND_HALF_UP);

        returnCouponResponse.setActivityMax(userActivityMax);
        returnCouponResponse.setTotalReturnCoupon(totalReturnCoupon);
        redisService.set(key, JSONObject.toJSONString(returnCouponResponse));
        redisService.expire(key, TokenConstants.EXPIRE_SECONDS);
    }

    private void addUsedActivityMax(BigDecimal ordersInfoActivityMax, String key) {
        ReturnCouponResponse returnCouponResponse = new ReturnCouponResponse();

        if (StringUtils.isNotEmpty(redisService.get(key))) {// 记录用户返现红包金额
            returnCouponResponse = com.alibaba.fastjson.JSONObject.parseObject(redisService.get(key), ReturnCouponResponse.class);
        } else {
            returnCouponResponse.setTotalReturnCoupon(BigDecimal.ZERO);
        }
        // 商品红包
        ordersInfoActivityMax = Optional.ofNullable(ordersInfoActivityMax)
                .orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);
        // 已使用红包
        BigDecimal usedActivityMax = Optional.ofNullable(returnCouponResponse.getUsedActivityMax())
                .orElse(BigDecimal.ZERO);
        // 用户红包
        BigDecimal userActivityMax = Optional.ofNullable(returnCouponResponse.getActivityMax())
                .orElse(new BigDecimal(680))
                .setScale(2, BigDecimal.ROUND_HALF_UP);

        // 已使用红包 += 商品红包
        usedActivityMax = usedActivityMax
                .add(ordersInfoActivityMax)
                .setScale(2, BigDecimal.ROUND_HALF_UP);
        // 用户红包 -= 商品红包
        if (ordersInfoActivityMax.compareTo(userActivityMax) > 0) {
            userActivityMax = BigDecimal.ZERO;
        } else {
            userActivityMax = userActivityMax
                    .subtract(ordersInfoActivityMax)
                    .setScale(2, BigDecimal.ROUND_HALF_UP);
        }

        returnCouponResponse.setUsedActivityMax(usedActivityMax);
        returnCouponResponse.setActivityMax(userActivityMax);
        redisService.set(key, com.alibaba.fastjson.JSONObject.toJSONString(returnCouponResponse));
        redisService.expire(key, TokenConstants.EXPIRE_SECONDS);
    }

    private void addUserdSubsidy(OrdersInfo ordersInfo, String recordKeyHead, String tokenUser) {
        String recordKey = recordKeyHead + tokenUser;
        log.info("addUserdSubsidy,recordKey={},ordersInfo={}", recordKey, JSONObject.toJSONString(ordersInfo));
        RecordSubsidyDataDto recordSubsidyDataDto = new RecordSubsidyDataDto();
        String recordSubsidyObj = redisService.get(recordKey);
        if (StringUtils.isNotEmpty(recordSubsidyObj)) {
            recordSubsidyDataDto = Optional.ofNullable(JSONObject.parseObject(recordSubsidyObj, RecordSubsidyDataDto.class)).orElse(new RecordSubsidyDataDto());
        } else {
            recordSubsidyDataDto.setReceived(BigDecimal.ZERO);
            recordSubsidyDataDto.setUsed(BigDecimal.ZERO);
            recordSubsidyDataDto.setToken(tokenUser);
        }

        BigDecimal received = Optional.ofNullable(recordSubsidyDataDto.getReceived()).orElse(BigDecimal.ZERO);
        BigDecimal used = Optional.ofNullable(recordSubsidyDataDto.getUsed()
                .add(ordersInfo.getActivityMax())
                .setScale(2, BigDecimal.ROUND_HALF_UP)).orElse(BigDecimal.ZERO);

        if (used.compareTo(received) > 0) {
            received = used;
        }

        recordSubsidyDataDto.setUsed(used);
        recordSubsidyDataDto.setReceived(received);
        recordSubsidyDataDto.setToken(Optional.ofNullable(recordSubsidyDataDto.getToken()).orElse(tokenUser));
        recordSubsidyDataDto.setReceiveTime(Optional.ofNullable(recordSubsidyDataDto.getReceiveTime()).orElse(new Date()));
        log.info("addUserdSubsidy,recordSubsidyDataDto={}", JSON.toJSONString(recordSubsidyDataDto));
        redisService.set(recordKey, JSON.toJSONString(recordSubsidyDataDto));
        redisService.expire(recordKey, ExpireTimeConstant.SUBSIDY_DATA_TIME);
    }

    private void addUserdSubsidy(OrdersInfo ordersInfo, String recordKeyHead, String tokenUser, Integer userId) {
//        RecordSubsidyDataDto recordSubsidyDataDto = new RecordSubsidyDataDto();

//        String recordKey = recordKeyHead + tokenUser;
//        String recordSubsidyObj = redisService.get(recordKey);
//        if (StringUtils.isNotEmpty(recordSubsidyObj)) {
//            recordSubsidyDataDto = Optional.ofNullable(JSONObject.parseObject(recordSubsidyObj, RecordSubsidyDataDto.class)).orElse(new RecordSubsidyDataDto());
//        }
//
//        BigDecimal received = Optional.ofNullable(recordSubsidyDataDto.getReceived()).orElse(BigDecimal.ZERO);
//        BigDecimal used = Optional.ofNullable(recordSubsidyDataDto.getUsed()
//                .add(ordersInfo.getActivityMax())
//                .setScale(2, BigDecimal.ROUND_HALF_UP)).orElse(BigDecimal.ZERO);
//
//        if (used.compareTo(received) > 0) {
//            received = used;
//        }
//
//        recordSubsidyDataDto.setUsed(used);
//        recordSubsidyDataDto.setReceived(received);
//        recordSubsidyDataDto.setToken(Optional.ofNullable(recordSubsidyDataDto.getToken()).orElse(tokenUser));
//        recordSubsidyDataDto.setReceiveTime(Optional.ofNullable(recordSubsidyDataDto.getReceiveTime()).orElse(new Date()));
//
//        redisService.set(recordKey, JSON.toJSONString(recordSubsidyDataDto));
//        redisService.expire(recordKey, ExpireTimeConstant.SUBSIDY_DATA_TIME);
        log.info("===userId={}===", userId);

        String recordKey = RedisConstants.RECORD_SUBSIDYKEY_USE_APP + userId;
        String recordSubsidyObj = "";
        try {
            recordSubsidyObj = redisService.get(recordKey);
        } catch (Exception e) {
        }
        BigDecimal used = BigDecimal.ZERO;
        if (StringUtils.isNotEmpty(recordSubsidyObj)) {
            used = BigDecimal.valueOf(Double.valueOf(recordSubsidyObj))
                    .add(ordersInfo.getActivityMax())
                    .setScale(2, BigDecimal.ROUND_HALF_UP);
        } else {
            used = BigDecimal.ZERO
                    .add(ordersInfo.getActivityMax())
                    .setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        redisService.set(recordKey, used.toString());
        redisService.expire(recordKey, Integer.parseInt(subsidyDay) * 24 * 60 * 60);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateH5PhoneOrderPay(Map<String, String> map) {
        String resOrderNo = map.get("out_trade_no");
        log.info("===updateH5PhoneOrderPay==={}", map);
        log.info("" + map.get("result_code").equals("SUCCESS"));
        if (map.get("result_code").equals("SUCCESS")) {
            // 检查订单状态
            // 获取订单信息
            // 获取锁
            RLock lock = redissonClient.getLock(RECHARGE_LOCK + resOrderNo);
            boolean b = false;
            try {
                b = lock.tryLock(0, 5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                lock.unlock();
            }
            log.info("回调成功等待获取锁！");
            if (b) {
                log.info("获取锁进入回调逻辑处理！");
                PhoneRechargeExample phoneRechargeExample = new PhoneRechargeExample();
                phoneRechargeExample.createCriteria().andOrderNoEqualTo(resOrderNo);
                List<PhoneRecharge> phoneRecharges = phoneRechargeMapper.selectByExample(phoneRechargeExample);
                PhoneRecharge phoneRechargeData = phoneRecharges.get(0);
                if (phoneRechargeData.getStatus() == 1) {
                    // 更新订单信息
                    PhoneRecharge phoneRecharge = new PhoneRecharge();
                    phoneRecharge.setPayCallback(JSONObject.toJSONString(map));
                    phoneRecharge.setPayCallbackTime(new Date());
                    phoneRecharge.setStatus(3);
                    PhoneRechargeExample example = new PhoneRechargeExample();
                    example.createCriteria()
                            .andOrderNoEqualTo(resOrderNo);
                    phoneRechargeMapper.updateByExampleSelective(phoneRecharge, example);

                    // 修改积分
                    String usesInfo = redisService.get(phoneRechargeData.getUuid());
                    if (usesInfo == null) {
                        throw new ApiException("充值失败，请重新充值!");
                    }
                    UsersResponse usersResponse = JSONObject.parseObject(usesInfo, UsersResponse.class);
                    usersResponse.setScore(usersResponse.getScore());
                    usersResponse.setTaskScore(usersResponse.getTaskScore() + phoneRechargeData.getGiveIntegral());
                    redisService.set(usersResponse.getToken(), JSONObject.toJSONString(usersResponse));
                    redisService.expire(usersResponse.getToken(), TokenConstants.EXPIRE_SECONDS);

                    PrepaidRefillDto prepaidRefillDto = new PrepaidRefillDto();
                    prepaidRefillDto.setOrderNo(resOrderNo);
                    prepaidRefillDto.setOperators(phoneRechargeData.getOperators());
                    // 发送队列
                    rabbitTemplate.convertAndSend(QueueConstants.RECHARGE_QUEUE, prepaidRefillDto);
                }

            }
            lock.unlock();
        }
    }

    @Override
    public void updateH5ISVPhoneOrderPay(WxPayOrderNotifyV3Result.DecryptNotifyResult notifyResult) {
        String resOrderNo = notifyResult.getOutTradeNo();
        log.info("===updateH5PhoneOrderPay==={}", notifyResult);
        log.info("" + notifyResult.getTradeState().equals("SUCCESS"));
        if (notifyResult.getTradeState().equals("SUCCESS")) {
            // 检查订单状态
            // 获取订单信息
            // 获取锁
            RLock lock = redissonClient.getLock(RECHARGE_LOCK + resOrderNo);
            boolean b = false;
            try {
                b = lock.tryLock(0, 5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                lock.unlock();
            }
            log.info("回调成功等待获取锁！");
            if (b) {
                log.info("获取锁进入回调逻辑处理！");
                PhoneRechargeExample phoneRechargeExample = new PhoneRechargeExample();
                phoneRechargeExample.createCriteria().andOrderNoEqualTo(resOrderNo);
                List<PhoneRecharge> phoneRecharges = phoneRechargeMapper.selectByExample(phoneRechargeExample);
                PhoneRecharge phoneRechargeData = phoneRecharges.get(0);
                if (phoneRechargeData.getStatus() == 1) {
                    // 更新订单信息
                    PhoneRecharge phoneRecharge = new PhoneRecharge();
                    phoneRecharge.setPayCallback(JSONObject.toJSONString(notifyResult));
                    phoneRecharge.setPayCallbackTime(new Date());
                    phoneRecharge.setStatus(3);
                    PhoneRechargeExample example = new PhoneRechargeExample();
                    example.createCriteria()
                            .andOrderNoEqualTo(resOrderNo);
                    phoneRechargeMapper.updateByExampleSelective(phoneRecharge, example);

                    // 修改积分
                    String usesInfo = redisService.get(phoneRechargeData.getUuid());
                    if (usesInfo == null) {
                        throw new ApiException("充值失败，请重新充值!");
                    }
                    UsersResponse usersResponse = JSONObject.parseObject(usesInfo, UsersResponse.class);
                    usersResponse.setScore(usersResponse.getScore());
                    usersResponse.setTaskScore(usersResponse.getTaskScore() + phoneRechargeData.getGiveIntegral());
                    redisService.set(usersResponse.getToken(), JSONObject.toJSONString(usersResponse));
                    redisService.expire(usersResponse.getToken(), TokenConstants.EXPIRE_SECONDS);

                    PrepaidRefillDto prepaidRefillDto = new PrepaidRefillDto();
                    prepaidRefillDto.setOrderNo(resOrderNo);
                    prepaidRefillDto.setOperators(phoneRechargeData.getOperators());
                    // 发送队列
                    rabbitTemplate.convertAndSend(QueueConstants.RECHARGE_QUEUE, prepaidRefillDto);
                }

            }
            lock.unlock();
        }
    }

    @Override
    public OrderResponse getH5OrdersPayStatus(Integer orderId, Integer payOrderId) {
        OrderResponse response = new OrderResponse();
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        response.setOrderNo(orders.getOrderNo());
        OrdersPay ordersPay = ordersPayMapper.selectByPrimaryKey(payOrderId);
        response.setPayStatus(Integer.valueOf(ordersPay.getPayType()));
        response.setRealTotalMoney(ordersPay.getAmount());
        response.setCreateTime(ordersPay.getCreateTime());
        response.setPaySource("aliPay".equals(ordersPay.getTradeType()) ? "aliPay" : "wx");
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAliPayOrdersPay(AlipayTradeQueryResponse response) {
        // 查询订单是否是处理中
        String resOrderNo = response.getOutTradeNo();
        log.info("updateAliPayOrdersPay,resOrderNo={}", resOrderNo);
        OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(resOrderNo);
        log.info("updateAliPayOrdersPay,pay={}", JSON.toJSON(pay));
        if (null == pay || !pay.getPayType().equals(PayPayTypeEnums.BEING_PROCESSED.getType())) {
            return;
        }
        if (response.getMsg().equalsIgnoreCase("SUCCESS")) {
            // 更新支付订单信息
//            pay.setTradeType(response.getBuyerUserType());
            pay.setTotalFee(new BigDecimal(response.getTotalAmount()).multiply(new BigDecimal(100)).intValue());
//            pay.setResText(String.valueOf(response));
            pay.setResText(JSONObject.toJSONString(response));
            if (null != response.getSendPayDate()) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    pay.setPayTime(sdf.format(response.getSendPayDate()));
                } catch (Exception e) {
                    log.error("===日期格式转换异常==={}", response.getSendPayDate());
                    pay.setPayTime(sdf.format(new Date()));
                }
//                pay.setPayTime(String.valueOf(response.getSendPayDate()));
            }
            pay.setPayType(PayPayTypeEnums.SUCCEED.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
            // 更新订单信息
            Orders orders = new Orders();
            orders.setPayType(OrderPayTypeEnums.online_pay.name());
            orders.setPaySource(OrderPaySource.alipay.name());
            orders.setIsPay(IsPayConstant.YES);
            orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
            orders.setPayTime(new Date());
            orders.setTradeNo(pay.getResOrderNo());
            OrdersExample example = new OrdersExample();
            example.createCriteria()
                    .andOrderNoEqualTo(pay.getOrderNo());
            ordersMapper.updateByExampleSelective(orders, example);
            // 获取订单信息
            Orders order = ordersDao.queryOrdersByOrderNo(pay.getOrderNo());

            // 获取订单明细
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(order.getId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            ordersInfoList.stream()
                    .forEach(item -> {
                        OrdersInfo ordersInfo = new OrdersInfo();
                        ordersInfo.setId(item.getId());
                        ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                        ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                        // 商品 减库存 加销量 店家加销量
                        productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                item.getIsWalletPay(), item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), order.getUserId());
                    });
            try {
                subStock(order.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (orderPushSwitch) {
                try {
                    log.info("上传供应链10============{}", order.getId());
                    ordersUpload(order.getId(),null);
                } catch (Exception e) {
                    log.error("上传供应链10失败============{}", e);
                }
            }
        } else {
            // 更新支付订单信息
            pay.setTradeType(response.getBuyerUserType());
            pay.setTotalFee(new BigDecimal(response.getTotalAmount()).multiply(new BigDecimal(100)).intValue());
            pay.setResText(String.valueOf(response));
            pay.setPayTime(String.valueOf(response.getSendPayDate()));
            pay.setPayType(PayPayTypeEnums.FAIL.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
        }
    }

    @Override
    public OrderResponse queryOrderInfoByNo(String childOrderNo, String source, UsersResponse usersResponse) {
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andChildOrderNoEqualTo(childOrderNo);
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        if (CollectionUtils.isEmpty(ordersInfoList)) {
            throw new ApiException("订单不存在!");
        }
        OrdersInfo ordersInfo = ordersInfoList.get(0);
        return queryAppOrderDetailByH5(ordersInfo, null);
    }

    @Override
    public List<OrderResponse> queryOrdersListByUserPhone(QueryOrdersRequest ordersRequest) {
        PageHelper.startPage(ordersRequest.getPageNum(), ordersRequest.getPageSize());
        List<Orders> ordersList = ordersDao.queryOrdersListByUserPhone(ordersRequest);
        if (CollectionUtils.isEmpty(ordersList)) {
            return new ArrayList<>();
        }
        List<Integer> orderInfoIds = ordersList.stream().filter(item -> item.getOrdersInfoId() !=null).map(Orders::getOrdersInfoId).collect(Collectors.toList());
        List<ReturnGoods> returnGoodsList = null;
        if (!CollectionUtils.isEmpty(orderInfoIds)) {
            ReturnGoodsExample example = new ReturnGoodsExample();
            example.createCriteria().andOrdersInfoIdIn(orderInfoIds);
            example.setOrderByClause("id desc");
            returnGoodsList = returnGoodsMapper.selectByExample(example);
        }
        List<ReturnGoods> finalReturnGoodsList = returnGoodsList;
        return ordersList.stream()
                .map(item -> {
                    OrderResponse orderResponse = new OrderResponse(item);
                    orderResponse.setIsPay(null == item.getIsPay() ? null : Integer.parseInt(item.getIsPay().toString()));
                    orderResponse.setOrderInfoList(this.getOrderInfoList(item.getId(), item.getOrdersInfoId()));
                    orderResponse.setType(OrdersStatusTypeEnums.getType(Integer.parseInt(item.getOrderStatus())));
                    orderResponse.setPayStatus((int) item.getIsPay());
                    //如果是待付款就返回支付截至时间
                    orderResponse.setPayExpirationTime(getDate(item.getCreateTime(), 1));
                    List<Integer> productStatusByOrderNo = ordersDao.getProductStatusByOrderNo(item.getId());
                    if (productStatusByOrderNo != null && productStatusByOrderNo.size() > 0) {
                        productStatusByOrderNo.stream().forEach(productStatus -> {
                            if (productStatus != null && productStatus == 2) {
                                orderResponse.setProductStatus(2);
                            }
                        });
                    }
                    //展示的实付价格
                    List<OrderInfoResponse> orderInfoList = orderResponse.getOrderInfoList();
                    final BigDecimal[] freight = {BigDecimal.ZERO};
                    final BigDecimal[] price = {BigDecimal.ZERO};
                    final BigDecimal[] totalMoney = {BigDecimal.ZERO};
                    orderInfoList.stream().forEach(orderInfo -> {
                        OrdersInfoFreightDto ordersInfoFreightDto = ordersDao.selectFreightByChildOrderNo(orderInfo.getChildOrderNo());
                        if (null != ordersInfoFreightDto) {
                            freight[0] = freight[0].add(ordersInfoFreightDto.getFreight());
                        }
                        price[0] = price[0].add(orderInfo.getProductPrice());
                        totalMoney[0] = totalMoney[0].add(orderInfo.getProductOprice().multiply(BigDecimal.valueOf(orderInfo.getProductSum())));
                    });
                    orderResponse.setProductPriceAndFreights(freight[0].add(price[0]));
                    orderResponse.setTotalMoney(totalMoney[0]);

                    // 查询是否有延迟发货
                    List<OrdersDelay> delayRemark = orderInfoDao.findDelayRemark(item.getOrdersInfoId());
                    if (!CollectionUtils.isEmpty(delayRemark) && delayRemark.size() > 0) {
                        orderResponse.setOrderDelay(delayRemark.get(0).getDelayRemark());
                        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(item.getOrdersInfoId());
                        orderResponse.setOrderDelay(ordersInfo.getOrderinfoStatus().equals("1") ?
                                delayRemark.get(0).getDelayRemark() : ordersInfo.getOrderinfoStatus().equals("2") ?
                                delayRemark.get(0).getDelayRemark() : null);
                    }

                    // 查询是否为严选官
                    if (null != ordersRequest.getUserId()) {
                        UsersInfo userInfoById = ordersDao.findUserInfoById(ordersRequest.getUserId());
                        orderResponse.setIsQuality(userInfoById.getIsQuality());
                    }
                    if (StringUtils.isEmpty(orderResponse.getActivityType())) {
                        orderResponse.setActivityType("");
                    }
                    if(item.getIsPay()==1) {
                        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(null != item.getOrdersInfoId() ? item.getOrdersInfoId():item.getId());
                        orderResponse.setRealTotalMoney(null == ordersInfo.getProductPrice() ? orderResponse.getProductPriceAndFreights():ordersInfo.getProductPrice());
                    }

                    BigDecimal realTotalMoney = Optional.ofNullable(orderResponse.getRealTotalMoney()).orElse(BigDecimal.ZERO);
                    orderResponse.setReducedPrice(null == orderResponse.getTotalMoney() ? BigDecimal.ZERO: orderResponse.getTotalMoney().subtract(realTotalMoney));
                    if (!CollectionUtils.isEmpty(finalReturnGoodsList)) {
                        List<ReturnGoods> collect = finalReturnGoodsList.stream().filter(item2 -> item.getOrdersInfoId().equals(item2.getOrdersInfoId())).collect(Collectors.toList());
                        orderResponse.setServiceNo(CollectionUtils.isEmpty(collect) ? null : collect.get(0).getServiceNo());
                    }
                    return orderResponse;
                }).collect(Collectors.toList());
    }


    @Override
    public List<OrderResponse> getOrdersList(QueryOrdersRequest ordersRequest) {
        PageHelper.startPage(ordersRequest.getPageNum(), ordersRequest.getPageSize());
        List<Orders> ordersList = new ArrayList<>();
        //分三种情况
        //全部
        if (ordersRequest.getType().equals("ALL")) {
            if (StringUtil.isEmpty(ordersRequest.getContent())) {
                // 普通查询
                ordersList = ordersDao.queryOrdersListAll(ordersRequest);
            } else {
                // 模糊查询
                ordersList = ordersDao.queryOrdersListByName(ordersRequest);
            }
        }
        //待付款
        else if (ordersRequest.getType().equals("OBLIGATION")) {
            if (StringUtil.isEmpty(ordersRequest.getContent())) {
                // 普通查询
                ordersList = ordersDao.queryOrdersList(ordersRequest);
            } else {
                // 模糊查询
                ordersList = ordersDao.queryOrdersListByName(ordersRequest);
            }
        }
        //其他
        else if (!ordersRequest.getType().equals("OBLIGATION") && !ordersRequest.getType().equals("ALL")) {
            if (StringUtil.isEmpty(ordersRequest.getContent())) {
                // 普通查询
                ordersList = ordersDao.queryOrdersListOrder(ordersRequest);
            } else {
                // 模糊查询
                ordersList = ordersDao.queryOrdersListByName(ordersRequest);
            }
        }
        if (CollectionUtils.isEmpty(ordersList)) {
            return new ArrayList<>();
        }
        List<GroupBuyUserRel> groupOrderList = yxGroupBuyUserRelService.queryCurUserJoinGroupId(ordersRequest.getUserId());
        log.info("===groupOrderList==={}", groupOrderList.size());
        List<Orders> resultList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(groupOrderList)) {
            List<String> myOrderNos = groupOrderList.stream().map(GroupBuyUserRel::getOrderNo).collect(Collectors.toList());
            log.info("===myOrderNos==={}", myOrderNos);
            ordersList.stream().forEach(order -> {
                log.info("===order.getOrderNo==={}", order.getOrderNo());
                log.info("===myOrderNos.contains(order.getOrderNo())==={}", myOrderNos.contains(order.getOrderNo()));
                if (!myOrderNos.contains(order.getOrderNo())) {
                    resultList.add(order);
                }
            });
        } else {
            resultList.addAll(ordersList);
        }
        return resultList.stream()
                .map(item -> {
                    OrderResponse orderResponse = new OrderResponse(item);
                    orderResponse.setOrderInfoList(this.getOrderInfoList(item.getId(), item.getOrdersInfoId()));
                    orderResponse.setType(OrdersStatusTypeEnums.getType(Integer.parseInt(item.getOrderStatus())));
                    orderResponse.setPayStatus((int) item.getIsPay());
                    //如果是待付款就返回支付截至时间
                    orderResponse.setPayExpirationTime(getDate(item.getCreateTime(), 1));
                    List<Integer> productStatusByOrderNo = ordersDao.getProductStatusByOrderNo(item.getId());
                    if (productStatusByOrderNo != null && productStatusByOrderNo.size() > 0) {
                        productStatusByOrderNo.stream().forEach(productStatus -> {
                            if (productStatus != null && productStatus == 2) {
                                orderResponse.setProductStatus(2);
                            }
                        });
                    }
                    //展示的实付价格
                    List<OrderInfoResponse> orderInfoList = orderResponse.getOrderInfoList();
                    final BigDecimal[] freight = {BigDecimal.ZERO};
                    final BigDecimal[] price = {BigDecimal.ZERO};
                    final BigDecimal[] totalMoney = {BigDecimal.ZERO};
                    orderInfoList.stream().forEach(orderInfo -> {
                        OrdersInfoFreightDto ordersInfoFreightDto = ordersDao.selectFreightByChildOrderNo(orderInfo.getChildOrderNo());
                        if (null != ordersInfoFreightDto) {
                            freight[0] = freight[0].add(ordersInfoFreightDto.getFreight());
                        }
                        price[0] = price[0].add(orderInfo.getProductPrice());
                        totalMoney[0] = totalMoney[0].add(orderInfo.getProductOprice().multiply(BigDecimal.valueOf(orderInfo.getProductSum())));
                    });
                    orderResponse.setProductPriceAndFreights(freight[0].add(price[0]));
                    orderResponse.setTotalMoney(totalMoney[0]);

                    // 查询是否有延迟发货
                    List<OrdersDelay> delayRemark = orderInfoDao.findDelayRemark(item.getOrdersInfoId());
                    if (!CollectionUtils.isEmpty(delayRemark) && delayRemark.size() > 0) {
                        orderResponse.setOrderDelay(delayRemark.get(0).getDelayRemark());
                        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(item.getOrdersInfoId());
                        orderResponse.setOrderDelay(ordersInfo.getOrderinfoStatus().equals("1") ?
                                delayRemark.get(0).getDelayRemark() : ordersInfo.getOrderinfoStatus().equals("2") ?
                                delayRemark.get(0).getDelayRemark() : null);
                    }

                    // 查询是否为严选官
                    if (null != ordersRequest.getUserId()) {
                        UsersInfo userInfoById = ordersDao.findUserInfoById(ordersRequest.getUserId());
                        orderResponse.setIsQuality(userInfoById.getIsQuality());
                    }
                    if (StringUtils.isEmpty(orderResponse.getActivityType())) {
                        orderResponse.setActivityType("");
                    }
                    return orderResponse;
                }).collect(Collectors.toList());
    }

    /**
     * 计算初始时间加一小时
     *
     * @param date 初始时间
     * @return
     */
    public static Date getDate(Date date, Integer hour) {
        Calendar cal = null;
        try {
            cal = Calendar.getInstance();
            cal.setTime(date);
            // 24小时制
            cal.add(Calendar.HOUR, hour);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cal.getTime();
    }

    @Override
    public List<OrderResponse> getH5OrdersList(QueryOrdersRequest ordersRequest) {
        PageHelper.startPage(ordersRequest.getPageNum(), ordersRequest.getPageSize());
        List<Orders> ordersList;
//        if(StringUtils.isNotEmpty(TokenUtil.getVisitorId())){
//            log.info("==========当前用户浏览器的唯一标识是：{} ==========",TokenUtil.getVisitorId());
//            List<Integer> usersByVisitorId = usersMapper.getUsersByVisitorId(TokenUtil.getVisitorId());
//            if(usersByVisitorId.size() == 1){
//                //用userId查询
//                ordersRequest.setH5Token("");
//                ordersRequest.setUserId(usersByVisitorId.get(0));
//            }
//        }
        if (StringUtil.isEmpty(ordersRequest.getContent())) {
            // 普通查询
            ordersList = ordersDao.queryOrdersList(ordersRequest);
        } else {
            // 模糊查询
            ordersList = ordersDao.queryOrdersListByName(ordersRequest);
        }
        log.debug(JSONObject.toJSONString(ordersList));
        return ordersList.stream()
                .map(item -> {
                    OrderResponse orderResponse = new OrderResponse(item);
                    orderResponse.setIsPay(null == item.getIsPay() ? null : Integer.parseInt(item.getIsPay().toString()));
                    orderResponse.setOrderInfoList(this.getOrderInfoList(item.getId(), null));
                    orderResponse.setType(OrdersStatusTypeEnums.getType(Integer.parseInt(item.getOrderStatus())));

                    OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
                    ordersInfoExample.createCriteria().andOrderIdEqualTo(item.getId());
                    List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
                    ordersInfos.stream().forEach(x -> {
                        List<OrdersDelay> delayRemark = orderInfoDao.findDelayRemark(x.getId());
                        if (!CollectionUtils.isEmpty(delayRemark)) {
                            orderResponse.setOrderDelay(x.getOrderinfoStatus().equals("1") ?
                                    delayRemark.get(0).getDelayRemark() : x.getOrderinfoStatus().equals("2") ?
                                    delayRemark.get(0).getDelayRemark() : null);
                        }
                        Product product = productMapper.selectByPrimaryKey(x.getProductId());
                        if (null != product) {
                            orderResponse.setPlatformData(product.getPlatformData());
                        }
                    });
                    if (!CollectionUtils.isEmpty(orderResponse.getOrderInfoList())) {
                        orderResponse.setServiceNo(orderResponse.getOrderInfoList().get(0).getServiceNo());
                    }
                    return orderResponse;
                }).collect(Collectors.toList());
    }

    @Override
    public void writeOrderAddress(WriteOrderAddressRequest request) {
        Orders orders;
        if (StringUtils.isNotBlank(request.getOrderNo())){
            orders = ordersMapper.selectByOrderNo(request.getOrderNo());
        }else{
            orders = ordersMapper.selectByPrimaryKey(request.getOrderId());
        }
        if (null == orders) {
            throw new ApiException("订单不存在");
        }
        if (OrdersPayStatusEnum.PAY.equals(orders.getIsPay()) || OrderStatusEnums.UNSHIPPED.getValue().equals(orders.getOrderStatus())) {
            throw new ApiException("订单已支付，如需修改收货地址请联系客服！");
        }
        String userAddress = request.getProvince() + request.getCity() + request.getArea() + request.getAddress();
        orders.setUserAddress(userAddress);
        orders.setProvince(request.getProvince());
        orders.setCity(request.getCity());
        orders.setArea(request.getArea());
        orders.setAddress(request.getAddress());
        orders.setTel(request.getTel());
        orders.setUserName(request.getUserName());
        orders.setUserPhone(request.getTel());
        Integer userId = usersClient.h5GetUserIdByTel(request.getTel(), orders.getChannel(), TokenUtil.getToken());
        orders.setUserId(userId);
        ordersMapper.updateByPrimaryKeySelective(orders);
        //保存用户地址
        UsersAddress usersAddress = usersAddressMapper.selectByUserId(userId);
        if (null != usersAddress) {
            usersAddress.setName(request.getUserName());
            usersAddress.setTel(request.getTel());
            usersAddress.setSort(1);
            usersAddress.setProvince(request.getProvince());
            usersAddress.setCity(request.getCity());
            usersAddress.setArea(request.getArea());
            usersAddress.setAddress(request.getAddress());
            usersAddress.setStatus((byte)1);
            usersAddress.setUpdateTime(new Date());
            usersAddressMapper.updateByPrimaryKey(usersAddress);
        } else {
            usersAddress = new UsersAddress();
            usersAddress.setUserId(userId);
            usersAddress.setName(request.getUserName());
            usersAddress.setTel(request.getTel());
            usersAddress.setSort(1);
            usersAddress.setProvince(request.getProvince());
            usersAddress.setCity(request.getCity());
            usersAddress.setArea(request.getArea());
            usersAddress.setAddress(request.getAddress());
            usersAddress.setStatus((byte)1);
            usersAddress.setCreateTime(new Date());
            usersAddressMapper.insert(usersAddress);
        }
        //推送推呀事件信息
//        try{
//            EffectParamRequest effectParamRequest = new EffectParamRequest();
//            effectParamRequest.setA_oId(request.getA_oId());
//            effectParamRequest.setSubType(4);
//            advertCallBackService.sendEffectData(effectParamRequest);
//        }catch (Exception e) {
//            log.error("推送到推呀事件信息错误:{}",e.getMessage());
//        }
    }

    @Override
    public void writeOrderAddressV2(WriteOrderAddressRequest request) {
        Orders orders;
        if (StringUtils.isNotBlank(request.getOrderNo())){
            orders = ordersMapper.selectByOrderNo(request.getOrderNo());
        }else{
            orders = ordersMapper.selectByPrimaryKey(request.getOrderId());
        }

        if (null == orders) {
            throw new ApiException("订单不存在");
        }
        if (OrdersPayStatusEnum.PAY.equals(orders.getIsPay()) || OrderStatusEnums.UNSHIPPED.getValue().equals(orders.getOrderStatus())) {
            throw new ApiException("订单已支付，如需修改收货地址请联系客服！");
        }
        String userAddress = request.getProvince() + request.getCity() + request.getArea() + request.getAddress();
        orders.setUserAddress(userAddress);
        orders.setProvince(request.getProvince());
        orders.setCity(request.getCity());
        orders.setArea(request.getArea());
        orders.setAddress(request.getAddress());
        orders.setTel(request.getTel());
        orders.setUserName(request.getUserName());
        orders.setUserPhone(request.getTel());
        ordersMapper.updateByPrimaryKeySelective(orders);
        //保存用户地址
        UsersAddress usersAddress = usersAddressMapper.selectByUserId(orders.getUserId());
        if (null != usersAddress) {
            usersAddress.setName(request.getUserName());
            usersAddress.setTel(request.getTel());
            usersAddress.setSort(1);
            usersAddress.setProvince(request.getProvince());
            usersAddress.setCity(request.getCity());
            usersAddress.setArea(request.getArea());
            usersAddress.setAddress(request.getAddress());
            usersAddress.setStatus((byte)1);
            usersAddress.setUpdateTime(new Date());
            usersAddressMapper.updateByPrimaryKey(usersAddress);
        } else {
            usersAddress = new UsersAddress();
            usersAddress.setUserId(orders.getUserId());
            usersAddress.setName(request.getUserName());
            usersAddress.setTel(request.getTel());
            usersAddress.setSort(1);
            usersAddress.setProvince(request.getProvince());
            usersAddress.setCity(request.getCity());
            usersAddress.setArea(request.getArea());
            usersAddress.setAddress(request.getAddress());
            usersAddress.setStatus((byte)1);
            usersAddress.setCreateTime(new Date());
            usersAddressMapper.insert(usersAddress);
        }
    }

    @Override
    public List<OrderInfoResponse> getOrderInfoList(Integer orderId, Integer ordersInfoId) {
//        OrdersInfoExample example = new OrdersInfoExample();
//        example.createCriteria()
//                .andOrderIdEqualTo(orderId);
//        List<OrdersInfo> orderInfoList = ordersInfoMapper.selectByExample(example);
        if (null == orderId) {
            return new ArrayList<>();
        }
        List<OrderInfoResponse> list = ordersDao.findByOrderId(orderId, ordersInfoId);
        list.stream().forEach(item -> {
            ReturnGoodsExample returnGoodsExample = new ReturnGoodsExample();
            returnGoodsExample.createCriteria().andOrdersInfoIdEqualTo(item.getId());
            returnGoodsExample.setOrderByClause("id desc");
            List<ReturnGoods> ReturnGoodsList = returnGoodsMapper.selectByExample(returnGoodsExample);
            if (!CollectionUtils.isEmpty(ReturnGoodsList)) {
                item.setStatus(ReturnGoodsList.get(0).getStatus());
                item.setServiceNo(ReturnGoodsList.get(0).getServiceNo());
            }
            if (StringUtils.isEmpty(item.getActivityType())) {
                item.setActivityType("");
            }
        });
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(item -> {
                item.setProductPrice(item.getProductPrice().multiply(BigDecimal.valueOf(item.getProductSum())));
                item.setReducedPrice(item.getProductOprice().multiply(BigDecimal.valueOf(item.getProductSum())).subtract(item.getProductPrice()));
                Dynamic dynamic = ordersDao.findAllById(item.getId());
                if (null != dynamic) {
                    item.setDynamicFlag(true);
                    item.setDynamicStatus(Integer.valueOf(dynamic.getStatus()));
                } else {
                    item.setDynamicFlag(false);
                }
                if (null != item.getProductPrice()) {
                    int money = item.getProductPrice().multiply(new BigDecimal(0.3)).setScale(0, BigDecimal.ROUND_UP).intValue();
                    if (money < 10) {
                        item.setIncomeAmount(10);
                    } else {
                        item.setIncomeAmount(money);
                    }
                } else {
                    item.setIncomeAmount(10);
                }
            });
        }
        return list;
//        return orderInfoList.stream().map(OrderInfoResponse::new).collect(Collectors.toList());
    }

    @Override
    public List<OrderInfoResponse> getScoreOrderInfoList(Integer userId) {
        List<OrdersInfo> ordersInfoList = ordersDao.getOrderInfoListByActivityType(userId, ActivityTypeEnums.CASH_SCORE.name());
        return ordersInfoList.stream().map(OrderInfoResponse::new).collect(Collectors.toList());
    }

    @Override
    public List<OrderInfoResponse> getScoreOrderInfoList(String h5Token) {
        List<OrdersInfo> ordersInfoList = ordersDao.getOrderInfoListByToken(h5Token, ActivityTypeEnums.CASH_SCORE.name());
        return ordersInfoList.stream().map(OrderInfoResponse::new).collect(Collectors.toList());
    }

    @Override
    public List<OrderInfoResponse> getNewProOrderInfoList(Integer userId) {
        List<OrdersInfo> ordersInfoList = ordersDao.getOrderInfoListByActivityType(userId, ActivityTypeEnums.NEW_PRO.name());
        return ordersInfoList.stream()
                .map(OrderInfoResponse::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<DynamicOrderResponse> getDynamicOrderList(Integer id, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        OrdersExample example = new OrdersExample();
        example.createCriteria()
                .andOrderStatusIn(Arrays.asList(String.valueOf(OrdersStatusTypeEnums.UNSHIPPED.getCode()),
                        String.valueOf(OrdersStatusTypeEnums.SHIPPED.getCode()),
                        String.valueOf(OrdersStatusTypeEnums.COMPLETED.getCode())))
                .andUserIdEqualTo(id);
        List<Orders> ordersList = ordersMapper.selectByExample(example);
        return ordersList.stream()
                .map(item -> {
                    DynamicOrderResponse order = new DynamicOrderResponse();
                    BeanUtils.copyProperties(item, order);
                    OrdersInfoExample infoExample = new OrdersInfoExample();
                    infoExample.createCriteria()
                            .andOrderIdEqualTo(item.getId())
                            .andIsAppraiseEqualTo(DynamicConstant.IS_APPRAISE_NO);
                    List<OrdersInfo> orderInfoList = ordersInfoMapper.selectByExample(infoExample);
                    order.setOrderInfoList(orderInfoList.stream()
                            .map(DynamicOrderInfoResponse::new)
                            .collect(Collectors.toList()));
                    return order;
                })
                .collect(Collectors.toList());
    }


    @Override
    public List<OrderInfoResponse> getDynamicOrderListV2(Integer id, Integer pageNum, Integer pageSize) {
        List<OrderInfoResponse> orderInfoResponseList = new ArrayList<>();
        PageHelper.startPage(pageNum, pageSize);
        OrdersExample example = new OrdersExample();
        example.createCriteria()
                .andOrderStatusIn(Arrays.asList(String.valueOf(OrdersStatusTypeEnums.UNSHIPPED.getCode()),
                        String.valueOf(OrdersStatusTypeEnums.SHIPPED.getCode()),
                        String.valueOf(OrdersStatusTypeEnums.COMPLETED.getCode())))
                .andUserIdEqualTo(id);
        List<Orders> ordersList = ordersMapper.selectByExample(example);
        for (Orders orders : ordersList) {
            OrdersInfoExample infoExample = new OrdersInfoExample();
            infoExample.createCriteria()
                    .andOrderIdEqualTo(orders.getId());
            List<OrdersInfo> orderInfoList = ordersInfoMapper.selectByExample(infoExample);
            List<OrderInfoResponse> list = orderInfoList
                    .stream()
                    .map(item -> {
                        OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
                        BeanUtils.copyProperties(item, orderInfoResponse);
                        if (DynamicConstant.IS_APPRAISE_BETWEEN.equals(item.getIsAppraise()) ||
                                DynamicConstant.IS_APPRAISE_YES.equals(item.getIsAppraise())) {
                            orderInfoResponse.setIsPublish(1);
                        }
                        String activityType = item.getActivityType();
                        activityType = StringUtils.isBlank(activityType) ? "COMMON" : activityType;
                        PageButton productTips = commonService.getPageButton(activityType, "PRODUCT_TIPS");
                        // 普通商品
                        ProductResponse productResponse = productService.queryProductById(item.getProductId());
                        productResponse.setPageButton(productTips);
                        productTips.setCopywriter(productService.getCopywriter(productResponse, null));
                        orderInfoResponse.setPageButton(productTips);
                        return orderInfoResponse;
                    })
                    .collect(Collectors.toList());
            orderInfoResponseList.addAll(list);
        }
        return orderInfoResponseList;
    }

    @Override
    public OrderInfoResponse getOrderInfoById(Integer id) {
        return new OrderInfoResponse(Optional.ofNullable(ordersInfoMapper.selectByPrimaryKey(id))
                .orElseThrow(() -> new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_NON_EXISTENT))));
    }

    @Override
    public OrdersInfo getOrdersInfoById(Integer id) {
        return ordersInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public OrdersInfo getOrdersInfoByExpressNo(String expressNo) {
        return ordersInfoMapper.selectByExpressNo(expressNo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderInfo(OrderInfoResponse orderInfo) {
        OrdersInfo orders = new OrdersInfo();
        orders.setId(orderInfo.getId());
        orders.setIsAppraise(orderInfo.getIsAppraise());
        ordersInfoMapper.updateByPrimaryKeySelective(orders);
    }

    @Override
    public LogisticsResponse checkLogistics(Integer orderInfoId, UsersResponse currentUser) {
        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(orderInfoId);
        Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());
        // 对比用户信息
        OrdersPayExample example = new OrdersPayExample();
        example.createCriteria()
                .andOrderNoEqualTo(orders.getOrderNo());
        List<OrdersPay> ordersPays = ordersPayMapper.selectByExample(example);
        OrdersPay ordersPay = null;
        if (!CollectionUtils.isEmpty(ordersPays)) {
            ordersPay = ordersPays.get(0);
        }
        LogisticsResponse logisticsResponse = new LogisticsResponse()
                .setOrderNo(orders.getOrderNo())
                .setBuyTime(orders.getCreateTime())
                .setPayType(PayTypeEnums.getPayType(orders.getPaySource()))
                .setPayTime(null == ordersPay ? ordersInfo.getCreateTime() : ordersPay.getCreateTime())
                .setProTotalMoney(orders.getTotalMoney())
                .setPayMoney(null == ordersPay ? orders.getDeductionMoney() : ordersPay.getAmount())
                .setOrderStatus(ordersInfo.getOrderinfoStatus())
                .setUserAddress(orders.getUserAddress())
                .setUserPhone(orders.getUserPhone())
                .setUserName(orders.getUserName())
                .setOrdersInfo(ordersInfo);
//        if (StringUtils.isNotEmpty(ordersInfo.getExpressCompanyNo()) && StringUtils.isNotEmpty(ordersInfo.getExpressNo())) {
//            // 快递记录
//            ExpressOrdersExample expressOrdersExample = new ExpressOrdersExample();
//            expressOrdersExample.createCriteria()
//                    .andNoEqualTo(ordersInfo.getExpressNo());
//            expressOrdersExample.setOrderByClause("create_time desc");
//        List<ExpressOrders> expressOrders = expressOrdersMapper.selectByExampleWithBLOBs(expressOrdersExample);
//
//            // 配送公司记录
//            ExpressDicExample expressDicExample = new ExpressDicExample();
//            expressDicExample.createCriteria().andExpressValueEqualTo(ordersInfo.getExpressCompanyNo());
//            expressDicExample.setOrderByClause("id desc");
//            List<ExpressDic> expressDics = expressDicMapper.selectByExample(expressDicExample);
//            ExpressCompanyExample expressCompanyExample = new ExpressCompanyExample();
//            expressCompanyExample.createCriteria()
//                    .andCompanyNoEqualTo(ordersInfo.getExpressCompanyNo());
//            List<ExpressCompany> expressCompanies = expressCompanyMapper.selectByExample(expressCompanyExample);
//            if (expressOrders.size() > 0 && expressDics.size() > 0) {
//                ExpressOrders expressOrder = expressOrders.get(0);
//                ExpressDic expressDic = expressDics.get(0);
//                logisticsResponse
//                        .setOrderShipNo(expressOrder.getExpressEno())
//                        .setShipName(expressDic.getExpressKey())
//                        .setLogo(expressCompanies.size() > 0 ? expressCompanies.get(0).getLogo() : null)
//                        .setDeliveryInfo(JSONArray.parseArray(expressOrder.getInfoText()));
//            }
//        }
        if (orders.getUserPhone() != null && ordersInfo.getExpressCompanyNo() != null && ordersInfo.getExpressNo() != null) {
            Map<String, String> map = new HashMap<>();
            map.put("expressCompany", ordersInfo.getExpressCompanyNo());
            map.put("expressNo", ordersInfo.getExpressNo());
            String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/order/checkLogistics", map, supplyApiConfig.getHeadsMap());
            if (null != resultJson) {
                Map<String, String> res = null;
                try {
                    Gson gson = new Gson();
                    res = gson.fromJson(resultJson, new TypeToken<Map<String, String>>() {
                    }.getType());
                } catch (Exception e) {

                }
                logisticsResponse
                        .setOrderShipNo(res.get("expressEno"))
                        .setShipName(res.get("expressKey"))
                        .setDeliveryInfo(JSONArray.parseArray(res.get("infoText")));
            }
        }
        return logisticsResponse;
    }

    @Override
    public List<OrderResponse> getOrdersListByTel(QueryOrdersRequest ordersRequest) {
        PageHelper.startPage(ordersRequest.getPageNum(), ordersRequest.getPageSize());
        List<Orders> ordersList = ordersDao.queryOrdersListByTel(ordersRequest);
        return ordersList.stream()
                .map(item -> {
                    OrderResponse orderResponse = new OrderResponse(item);
                    orderResponse.setOrderInfoList(this.getOrderInfoList(item.getId(), null));
                    orderResponse.setType(OrdersStatusTypeEnums.getType(Integer.parseInt(item.getOrderStatus())));
                    return orderResponse;
                }).collect(Collectors.toList());
    }

    @Override
    public Integer h5CreateOrder(H5CreateOrderRequest request) {
        //冻结库存前查一下库存是否足够用
        log.info("=============冻结库存前查一下库存是否足够用1=====================参数{},{}", request.getProductId(), request.getProductSpecId());
        boolean b = checkProductStock(request.getProductId(), request.getProductSpecId(), request.getProductSum());
        if (!b) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
        }
        Integer orderId = createOrderService.get(request.getCreateType()).createOrder(request);
        try {
            ProductStockFrozen(orderId);
        } catch (Exception e) {
            log.error("=========下单时冻结库存失败2======={}=={}", orderId, e);
        }




        //推送百度事件信息
//        try{
//            String h5Token = TokenUtil.getToken();
//            new Thread(()->{
//                String usesInfo = redisService.get(h5Token);
//                String a_oId = "";
//                if (StringUtils.isNotBlank(usesInfo)) {
//                    UsersResponse usersResponse = com.alibaba.fastjson.JSONObject.parseObject(usesInfo, UsersResponse.class);
//                    if (StringUtils.isNotBlank(usersResponse.getAoId())) {
//                        a_oId =  usersResponse.getAoId();
//                    }
//                }
//                if(StringUtils.isNotBlank(a_oId)){
//                    List<ConversionType> conversionTypes = new ArrayList<>();
//                    // 编辑一条转化数据
//                    ConversionType cv = new ConversionType();
//                    cv.setLogidUrl(a_oId); // 设置落地页url
//                    cv.setNewType(45); // 设置转化类型
//                    cv.setConvertTime(System.currentTimeMillis() / 1000);
//                    conversionTypes.add(cv);
//                    BaiduApiUtil.sendConvertData(baiduToken, conversionTypes);
//                }
//            }).start();
//        }catch (Exception e) {
//            log.error("推送到百度事件信息错误:{}",e.getMessage());
//        }
        return orderId;
    }

    @Override
    public String updateOrderRedpacket(String orderNo) {
        Orders orders = ordersDao.queryOrdersByOrderNo(orderNo);
        if (orders!=null && orders.getIsPay().byteValue() == (byte) 1){
            return "当前订单已支付,无法领取红包";
        }
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectOrderInfoByOrderId(orders.getId());
        Integer productId = ordersInfoList.get(0).getProductId();
        Product product = productMapper.selectByPrimaryKey(productId);

        if (orders!=null && orders.getDeductionMoney()==null){
            BigDecimal realTotalMoney = orders.getRealTotalMoney();
            //使用优惠卷
            BigDecimal couponNum =null;
            if (product.getOriginalPrice()!=null && product.getPrice()!=null){
                couponNum = product.getOriginalPrice().subtract(product.getPrice());
                if (couponNum.compareTo(BigDecimal.ZERO) > 0 && (realTotalMoney.subtract(couponNum)).compareTo(BigDecimal.ZERO) > 0){
                    realTotalMoney = realTotalMoney.subtract(couponNum);
                    Orders record = new Orders();
                    record.setId(orders.getId());
                    record.setRealTotalMoney(realTotalMoney);
                    record.setDeductionMoney(couponNum);
                    ordersMapper.updateByPrimaryKeySelective(record);
                    return couponNum.toString();
                }
            }
        }
        return orders.getDeductionMoney().toString();
    }

    @Async
    @Override
    public void checkPaymentChannelStatus(String platform) {

    }

    @Async
    @Override
    public void checkPaymentChannelStatus(String platform,String domainUrl) {
        try {
            if("hftx".equals(platform)){
                String aliPayKey = "paySysStatus:upay";
                String payStatus = redisService.get(aliPayKey);
                if(StringUtils.isNotBlank(payStatus)){
                    return;
                }else {
                    redisService.set(aliPayKey,"1",60);
                    List<OrdersPay> payOrders = ordersMapper.getRecentOrders(30, 1,4,domainUrl);
                    //支付成功或者重复支付的订单
                    if(org.apache.commons.collections.CollectionUtils.isNotEmpty(payOrders)){
                        List<OrdersPay> wxPaid = payOrders.stream().filter(e -> "2".equals(String.valueOf(e.getPayType())) || "4".equals(String.valueOf(e.getPayType()))).collect(Collectors.toList());
                        BigDecimal wxRate = new BigDecimal(wxPaid.size()).divide(new BigDecimal(payOrders.size()),  2, RoundingMode.HALF_UP);
                        if (wxRate.compareTo(new BigDecimal(0)) <= 0) {
                            FeiShuUtil.sendMsg("疑似hftx支付异常，当前支付率是：" + wxRate.multiply(new BigDecimal(100)).setScale(2).toString() + "%" + "<at user_id=\"all\">所有人</at>");
                        }
                    }
                }
            }
            if("upay".equals(platform)){
                String aliPayKey = "paySysStatus:upay";
                String payStatus = redisService.get(aliPayKey);
                if(StringUtils.isNotBlank(payStatus)){
                    return;
                }else {
                    redisService.set(aliPayKey,"1",60);
                    List<OrdersPay> payOrders = ordersMapper.getRecentOrders(30, 1,3,domainUrl);
                    //支付成功或者重复支付的订单
                    if(org.apache.commons.collections.CollectionUtils.isNotEmpty(payOrders)){
                        List<OrdersPay> wxPaid = payOrders.stream().filter(e -> "2".equals(String.valueOf(e.getPayType())) || "4".equals(String.valueOf(e.getPayType()))).collect(Collectors.toList());
                        BigDecimal wxRate = new BigDecimal(wxPaid.size()).divide(new BigDecimal(payOrders.size()),  2, RoundingMode.HALF_UP);
                        if (wxRate.compareTo(new BigDecimal(0)) <= 0) {
                            FeiShuUtil.sendMsg("疑似upay支付异常，当前支付率是：" + wxRate.multiply(new BigDecimal(100)).setScale(2).toString() + "%" + "<at user_id=\"all\">所有人</at>");
                        }
                    }
                }
            }
            if("aliPay".equals(platform)){

                //之前被风控过的域名不报警
                List<String> zfbBlackUrlList = Arrays.asList(zfbBlackUrl.split(","));
                if (zfbBlackUrlList.contains(domainUrl)){
                    log.info("domainUrl跳过,{}",domainUrl);
                    return;
                }


                String aliPayKey = "paySysStatus:aliPay:"+domainUrl;
                String payStatus = redisService.get(aliPayKey);
                if(StringUtils.isNotBlank(payStatus)){
                    return;
                }else {
                    redisService.set(aliPayKey,"1",intervalTime);
                    List<OrdersPay> payOrders = ordersMapper.getRecentOrders(alipayUnpayCount, 0,1,domainUrl);
                    //支付成功或者重复支付的订单
                    if(org.apache.commons.collections.CollectionUtils.isNotEmpty(payOrders)){
                        List<OrdersPay> wxPaid = payOrders.stream().filter(e -> "2".equals(String.valueOf(e.getPayType())) || "4".equals(String.valueOf(e.getPayType()))).collect(Collectors.toList());
                        BigDecimal wxRate = new BigDecimal(wxPaid.size()).divide(new BigDecimal(payOrders.size()),  2, RoundingMode.HALF_UP);
                        if (wxRate.compareTo(new BigDecimal(0)) <= 0) {
                            String alipayZeroNumKey = "alipayZeroNum";
                            String alipayZeroNum = redisService.get(alipayZeroNumKey);
                            redisService.increment(alipayZeroNumKey,1);
                            redisService.expire(alipayZeroNumKey,60*30);

                            //自动切换收款账号
                            try {
                                String zfbAccountSwitch = ordersDao.getSysConfig("zfbAccount_switch");
                                if (alipayZeroNum!=null && Integer.parseInt(alipayZeroNum)>2 && "true".equals(zfbAccountSwitch)){
                                    YxAlipayConfig alipayConfig = payConfigDao.findAliPayIdByWeight();
                                    if (alipayConfig != null){
                                        payConfigDao.updateAlipayStateById(alipayConfig.getId());
                                        YxAlipayConfig yxAlipayConfig = payConfigDao.findAliPayByState();
                                        FeiShuUtil.sendMsg(String.format("支付宝收款账号已自动切换到%s,请检查能否正常支付"+ "<at user_id=\"all\">所有人</at>",yxAlipayConfig.getAccount()));

                                        //切完做一个记录 过几分钟在报警
                                        redisService.set(aliPayKey,"1",60*5);
                                    }
                                }
                            } catch (Exception e) {
                                log.error("支付宝自动切换账号失败,{}",e);
                            }



                            //自动切换域名
                            String domainSwitch = ordersDao.getSysConfig("domain_switch");
                            if (alipayZeroNum!=null && Integer.parseInt(alipayZeroNum)>2 && "true".equals(domainSwitch)){
                                String newUrl = ordersDao.getUrlNewContent(domainUrl);
                                if (StringUtils.isNotBlank(newUrl)){
                                    Map<String, String> param = new HashMap<>();
                                    param.put("urlOld",domainUrl);
                                    param.put("urlNew",newUrl);
                                    String result= HttpClientUtil.doGet(shortUrl+"/admin/updateLongUrl",param);
                                    if (result != null && result.equals("ok")){
                                        FeiShuUtil.sendMsg(String.format("%s已自动切换到%s,请检查能否正常支付"+ "<at user_id=\"all\">所有人</at>",domainUrl,newUrl));
                                        redisService.remove(alipayZeroNumKey);
                                        //修改数据库
                                        ordersDao.updateDomainUrlStateByUrl(domainUrl);
                                        //切完做一个记录 过几分钟在报警
                                        redisService.set(aliPayKey,"1",60*5);
                                        //记录最新切换的域名
                                        redisService.set("zfbNewUrl",newUrl);
                                    }
                                }else{
                                    FeiShuUtil.sendMsg(newUrl+"未配置切换域名,请先配置");
                                }
                            }else{
                                FeiShuUtil.sendMsg(domainUrl+"疑似支付宝支付异常，当前支付率是：" + wxRate.multiply(new BigDecimal(100)).setScale(2).toString() + "%" + "<at user_id=\"all\">所有人</at>");
                            }
                        }
                    }
                }
            }
            if ("zsy".equals(platform)){
                //之前被风控过的域名不报警
                List<String> zfbBlackUrlList = Arrays.asList(zfbBlackUrl.split(","));
                if (zfbBlackUrlList.contains(domainUrl)){
                    log.info("domainUrl跳过,{}",domainUrl);
                    return;
                }

                String aliPayKey = "paySysStatus:aliPay:"+domainUrl;
                String payStatus = redisService.get(aliPayKey);
                if(StringUtils.isNotBlank(payStatus)){
                    return;
                }else {
                    redisService.set(aliPayKey,"1",intervalTime);
                    List<OrdersPay> payOrders = ordersMapper.getRecentOrders(alipayUnpayCount, 0,5,domainUrl);
                    //支付成功或者重复支付的订单
                    if(org.apache.commons.collections.CollectionUtils.isNotEmpty(payOrders)){
                        List<OrdersPay> wxPaid = payOrders.stream().filter(e -> "2".equals(String.valueOf(e.getPayType())) || "4".equals(String.valueOf(e.getPayType()))).collect(Collectors.toList());
                        BigDecimal wxRate = new BigDecimal(wxPaid.size()).divide(new BigDecimal(payOrders.size()),  2, RoundingMode.HALF_UP);
                        if (wxRate.compareTo(new BigDecimal(0)) <= 0) {
                            String alipayZeroNumKey = "alipayZeroNum";
                            String alipayZeroNum = redisService.get(alipayZeroNumKey);
                            redisService.increment(alipayZeroNumKey,1);
                            redisService.expire(alipayZeroNumKey,60*30);

                            //自动切换到我们自己的支付宝收款
                            String alipayflag =ordersDao.getSysConfig("ALI_PAY_FLAG");
                            if (StringUtils.isNotBlank(alipayflag)){
                                Map<String,String> alipayMap = com.alibaba.fastjson.JSON.parseObject(alipayflag,Map.class);
                                String aliPayCheckFlag = alipayMap.get("aliPayCheckFlag");
                                if (StringUtils.isNotBlank(aliPayCheckFlag) && "1".equals(aliPayCheckFlag)){
                                    ordersDao.updateAlipayFlag();
                                    FeiShuUtil.sendMsg("第三方支付已自动切换到我们自己的支付宝收款,请检查能否正常支付");
                                }
                            }


                            //自动切换域名
                            String domainSwitch = ordersDao.getSysConfig("domain_switch");
                            if (alipayZeroNum!=null && Integer.parseInt(alipayZeroNum)>2 && "true".equals(domainSwitch)){
                                String newUrl = ordersDao.getUrlNewContent(domainUrl);
                                if (StringUtils.isNotBlank(newUrl)){
                                    Map<String, String> param = new HashMap<>();
                                    param.put("urlOld",domainUrl);
                                    param.put("urlNew",newUrl);
                                    String result= HttpClientUtil.doGet(shortUrl+"/admin/updateLongUrl",param);
                                    if (result != null && result.equals("ok")){
                                        FeiShuUtil.sendMsg(String.format("%s已自动切换到%s,请检查能否正常支付"+ "<at user_id=\"all\">所有人</at>",domainUrl,newUrl));
                                        redisService.remove(alipayZeroNumKey);
                                        //修改数据库
                                        ordersDao.updateDomainUrlStateByUrl(domainUrl);
                                        //切完做一个记录 过几分钟在报警
                                        redisService.set(aliPayKey,"1",60*5);
                                        //记录最新切换的域名
                                        redisService.set("zfbNewUrl",newUrl);
                                    }
                                }else{
                                    FeiShuUtil.sendMsg(newUrl+"未配置切换域名,请先配置");
                                }
                            }else{
                                FeiShuUtil.sendMsg(domainUrl+"疑似第三方支付异常，当前支付率是：" + wxRate.multiply(new BigDecimal(100)).setScale(2).toString() + "%" + "<at user_id=\"all\">所有人</at>");
                            }
                        }
                    }
                }
            }
            if("wx".equals(platform)){
                String wxKey = "paySysStatus:wx:"+domainUrl;
                String payStatus = redisService.get(wxKey);
                if(StringUtils.isNotBlank(payStatus)){
                    return;
                }else {
                    redisService.set(wxKey,"1",60);
                    List<OrdersPay> payOrders = ordersMapper.getRecentOrders(50, 0,2,domainUrl);
                    if (org.apache.commons.collections.CollectionUtils.isNotEmpty(payOrders)){
                        //支付成功或者重复支付的订单
                        List<OrdersPay> wxPaid = payOrders.stream().filter(e -> "2".equals(String.valueOf(e.getPayType())) || "4".equals(String.valueOf(e.getPayType()))).collect(Collectors.toList());
                        BigDecimal wxRate = new BigDecimal(wxPaid.size()).divide(new BigDecimal(payOrders.size()), 2, RoundingMode.HALF_UP);
                        if (wxRate.compareTo(new BigDecimal(0)) <= 0) {
                            FeiShuUtil.sendMsg(domainUrl+"疑似微信支付异常，当前支付率是：" + wxRate.multiply(new BigDecimal(100)).setScale(2).toString() + "%" + "<at user_id=\"all\">所有人</at>");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("支付监控代码报错：{}",e);
        }
    }

    @Override
    public Integer h5CartCreateOrder(H5CartCreateOrderRequest request) {
        return createOrderService.get(request.getCreateType()).cartCreateOrder(request);
    }

    @Override
    public OrderResponse getH5OrderInfoByOrderNo(String orderNo, UsersResponse h5CurrentUser) {
        Orders orders = ordersMapper.selectByOrderNo(orderNo);
        Optional.ofNullable(orders).orElseThrow(() -> new ApiException("该订单不存在!"));
        return queryOrderDetail(orders, h5CurrentUser);
    }

    private OrderResponse queryOrderDetail(Orders orders, UsersResponse h5CurrentUser) {
        log.info("h5CurrentUser.getToken()={}, order.h5Toke={}", h5CurrentUser.getToken(), orders.getH5Token());
        OrderResponse response = new OrderResponse();
        response.setOrderId(orders.getId());
        response.setOrderNo(orders.getOrderNo());
        response.setTotalMoney(orders.getTotalMoney());
        response.setFreight(new BigDecimal(0));
        response.setPaySource(orders.getPaySource());

        OrdersInfoExample example = new OrdersInfoExample();
        example.createCriteria().andOrderIdEqualTo(orders.getId());
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(example);


        ordersInfoList.stream().forEach(item -> {
            ProductSpec productSpec = productSpecMapper.selectByPrimaryKey(item.getProductSpecId());
            if (null != productSpec) {
                item.setProductImg(productSpec.getProImg());
            }
        });

        String city = orders.getCity();

        OrdersInfo ordersInfo = ordersInfoList.get(0);
        //获取供应链运费模板
        FreightTemplateResponse freightTemplateResponse = getFreightTemplateResponse(ordersInfo.getProductId());
        Product product = productMapper.selectByPrimaryKey(ordersInfo.getProductId());
        //好评率
        response.setGoodRatio(getProductRatio(product));
        try{
            BigDecimal totalFreight = BigDecimal.ZERO;
            //默认以供应链的运费模板为主
            totalFreight = calculateFreight(freightTemplateResponse,ordersInfo.getProductSum(),city,orders.getProvince());

            //查询运费数据是否存在
            OrdersInfoFreightDto dto = ordersDao.selectFreightByChildOrderNo(ordersInfo.getChildOrderNo());
            if (null != dto) {
                //更新子订单运费
                ordersDao.updateFreight(totalFreight, ordersInfo.getChildOrderNo());
                //更新主订单支付金额
                orders.setTotalMoney(orders.getTotalMoney().subtract(dto.getFreight()).add(totalFreight));
                orders.setRealTotalMoney(orders.getRealTotalMoney().subtract(dto.getFreight()).add(totalFreight));
                ordersMapper.updateByPrimaryKeySelective(orders);
            } else {
                //新增运费数据
                createOrderInfoFreight(ordersInfo,orders,totalFreight,freightTemplateResponse.getId());
            }
            response.setFreight(totalFreight);

        }catch (Exception e) {
            log.info("计算h5计算运费错误：",e.getMessage());
            response.setFreight(BigDecimal.ZERO);
        }
        response.setRealTotalMoney(orders.getRealTotalMoney());
        if (null != ordersInfo.getIsWalletPay() && ordersInfo.getIsWalletPay() == 1) {
            response.setRealTotalMoney(response.getRealTotalMoney().add(ordersInfo.getWalletPrice()).setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        // 地址
        UsersAddress usersAddress = usersAddressMapper.selectByUserId(orders.getUserId());
        DefaultAddressDto defaultAddressDto = new DefaultAddressDto();
//        if (usersAddress != null) {
//            BeanUtils.copyProperties(usersAddress,defaultAddressDto);
//        } else {
            if (usersAddress!=null){
                defaultAddressDto.setId(usersAddress.getId());
            }
            defaultAddressDto.setProvince(orders.getProvince());
            defaultAddressDto.setCity(orders.getCity());
            defaultAddressDto.setArea(orders.getArea());
            defaultAddressDto.setAddress(orders.getAddress());
//        }
        response.setAddress(defaultAddressDto);
        response.setAddressText(orders.getUserAddress());
        response.setUserName(orders.getUserName());
        response.setTel(orders.getTel());
        // 钱包金额
        response.setWalletMoney(h5CurrentUser.getTotalMoney());
        response.setCreateTime(orders.getCreateTime());
        response.setOrderInfoList(ordersInfoList.stream().map(item -> {
            item.setWarehouse("");
            item.setWarehouseName("");
            OrderInfoResponse infoResponse = new OrderInfoResponse(item);
            ProductResponse productResponse = productService.getProductById(item.getProductId(), "");
            if (productResponse != null) {
                infoResponse.setStock(productResponse.getStock());
                infoResponse.setVolumeStr(productResponse.getVolumeStr());
                if (null != item.getIsWalletPay() && item.getIsWalletPay() == 1) {
                    infoResponse.setProductPrice(infoResponse.getProductPrice().add(item.getWalletPrice()).setScale(2, BigDecimal.ROUND_HALF_UP));
                }
                infoResponse.setActivityType(productResponse.getActivityType());
                infoResponse.setActivityMax(productResponse.getActivityMax());
                infoResponse.setActivityMin(productResponse.getActivityMin());
                infoResponse.setPageButton(productResponse.getPageButton());
                infoResponse.setRecImgFlag(productResponse.getRecImgFlag());
            }
            return infoResponse;
        }).collect(Collectors.toList()));
        response.setPayTypeList(Arrays.asList(commonService.getSysConfigValue(SysConfigConstants.PAY_LIST).split(",")));

        // ----------------------------------------------------计算各种优惠价格总和---------------------------------------------------------------------
        Map<String, Object> discountType = new HashMap<>();
        // 积分
        BigDecimal cashScoreActivityMax = new BigDecimal(0);           // 积分
        BigDecimal cashScoreActivityMin = new BigDecimal(0);           // 购买的积分
        BigDecimal cashScoreReducedPrice = new BigDecimal(0);           // 抵扣价格
        // 返积分
        BigDecimal returnScore = new BigDecimal(0);
        // 大额神券
        BigDecimal cashCouponReducedPrice = new BigDecimal(0);
        // 以旧换新
        BigDecimal oldForNewReducedPrice = new BigDecimal(0);

        for (OrdersInfo item : ordersInfoList) {
            Integer isDirectbuy = Optional.ofNullable(item.getIsDirectbuy()).orElse(0);
            // 只有 活动商品  + 不是直接购买  才累加优惠
            if (StringUtils.isNotBlank(item.getActivityType()) && isDirectbuy != 1) {
                // 活动类型
                switch (item.getActivityType()) {
                    case "CASH_SCORE":
                        // 兑换积分
                        cashScoreActivityMax = cashScoreActivityMax.add(item.getActivityMax());
                        cashScoreActivityMin = cashScoreActivityMin.add(Optional.ofNullable(item.getActivityMin()).orElse(BigDecimal.ZERO));
                        cashScoreReducedPrice = cashScoreReducedPrice.add(item.getProductOprice().subtract(item.getProductPrice()));
                        break;
                    case "GET_SCORE":
                    case "NEW_USER":
                        // 新人首单返积分、返积分 统一加积分
                        returnScore = returnScore.add(item.getActivityMax());
                        break;
                    case "CASH_COUPON":
                        cashCouponReducedPrice = cashCouponReducedPrice.add(item.getActivityMax());
                        break;
                    case "OLD_FOR_NEW":
                        // 以旧换新
                        oldForNewReducedPrice = oldForNewReducedPrice.add(item.getActivityMax());
                        break;
                }
            }
        }

        // 积分
        Map<String, Object> cashScore = new HashMap<>();
        cashScore.put("cashScoreActivityMax", cashScoreActivityMax.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScoreActivityMin", cashScoreActivityMin.setScale(2, BigDecimal.ROUND_UP));
        cashScore.put("cashScorePrice", cashScoreReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        discountType.put("cashScore", cashScore);
        // 返积分
        discountType.put("returnScore", returnScore.setScale(2, BigDecimal.ROUND_UP));
        // 大额神券
        discountType.put("cashCouponPrice", cashCouponReducedPrice.setScale(2, BigDecimal.ROUND_UP));
        // 以旧换新
        discountType.put("oldForNewPrice", oldForNewReducedPrice.setScale(2, BigDecimal.ROUND_UP));

        // 平台立减
        BigDecimal platformPrice = orders.getTotalMoney()
                .subtract(cashScoreReducedPrice)                // 积分抵扣
                .subtract(cashCouponReducedPrice)               // 优惠券
                .subtract(oldForNewReducedPrice)                // 以旧换新
                .subtract(orders.getRealTotalMoney())           // 实际支付价格
                .setScale(2, BigDecimal.ROUND_UP);
        discountType.put("platformPrice", platformPrice);
        response.setDiscountType(discountType);
        SysConfig wx_pay_flag = sysConfigMapper.selectByPrimaryKey("WX_PAY_FLAG");
        Map<String, String> map = JSONObject.parseObject(wx_pay_flag.getParamValue(), Map.class);
        response.setWxPayFlag(wx_pay_flag ==null ? "1": map.get("wxPayFlag"));
        response.setWxPayFlag2(wx_pay_flag ==null ? "1": map.get("wxPayFlag2"));
        SysConfig ali_pay_flag = sysConfigMapper.selectByPrimaryKey("ALI_PAY_FLAG");
        Map<String, String> map2 = JSONObject.parseObject(ali_pay_flag.getParamValue(), Map.class);
        response.setAliPayFlag(ali_pay_flag ==null ? "1": map2.get("aliPayFlag"));
        response.setAliPayCheckFlag(ali_pay_flag ==null ? "1": map2.get("aliPayCheckFlag"));
        return response;
    }

    @Override
    public String getProductRatio(Product product){
        String mapValue = null;
        //好评率
        Long aLong = redisService.hashSize(RedisConstants.PRODUCT_GOOD_RATIO);
        if(aLong > 0){
            try {
                mapValue = redisService.getMapString(RedisConstants.PRODUCT_GOOD_RATIO, product.getId().toString());
            } catch (Exception e) {
                BigDecimal endNum = BigDecimal.ZERO;
                if(StringUtils.isNotEmpty(product.getRatio()) && !"0".equals(product.getRatio())){
                    endNum = BigDecimal.valueOf(new Random().nextDouble()).add(new BigDecimal(product.getRatio())).setScale(1,RoundingMode.HALF_UP);
                }else {
                    endNum = BigDecimal.valueOf(new Random().nextDouble() * 1.5 + 98.5).setScale(1,RoundingMode.HALF_UP);
                }
                log.info("商品的好评率Redis不存在,{}",e.getMessage());
                mapValue = endNum.toString();
                redisService.add(RedisConstants.PRODUCT_GOOD_RATIO, product.getId().toString(),mapValue);
                //有效期7天
                redisService.expire(RedisConstants.PRODUCT_GOOD_RATIO,7 * 24 * 60 * 60);
            }
        }else{
            BigDecimal endNum = BigDecimal.ZERO;
            if(StringUtils.isNotEmpty(product.getRatio()) && !"0".equals(product.getRatio())){
                endNum = BigDecimal.valueOf(new Random().nextDouble()).add(new BigDecimal(product.getRatio())).setScale(1,RoundingMode.HALF_UP);
            }else {
                endNum = BigDecimal.valueOf(new Random().nextDouble() * 1.5 + 98.5).setScale(1,RoundingMode.HALF_UP);
            }
            mapValue = endNum.toString();
            redisService.add(RedisConstants.PRODUCT_GOOD_RATIO, product.getId().toString(),mapValue);
            //有效期7天
            redisService.expire(RedisConstants.PRODUCT_GOOD_RATIO,7 * 24 * 60 * 60);
        }
        return mapValue;
    }

    @Override
    public OrderResponse getH5OrderInfoById(Integer orderId, UsersResponse h5CurrentUser) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        Optional.ofNullable(orders).orElseThrow(() -> new ApiException("该订单不存在!"));
        return queryOrderDetail(orders, h5CurrentUser);
    }

    @Override
    public Map unifiedPay(String resOrderNo, String amount, String openid, String type) {
        try {
            // 发起微信支付
            WxAppPayDto wxAppPayDto = WxAppPayDto.builder()
                    .body("XXXX优品-商城")
                    .resOrderNo(resOrderNo)  //订单号
                    .realTotalMoney(amount)  // 金额 分
                    .openid(openid)
                    .build();
            log.info("调取微信支付：req: {}", JSONObject.toJSONString(wxAppPayDto));
            Map map = wxServiceMap.get("APP-" + type).doUnifiedRechargeOrder(wxAppPayDto);
            log.info("调取微信支付结果：res: {}", JSONObject.toJSONString(map));
            return map;
        } catch (Exception e) {
            log.error("==========》调微信失败e :{}", GlobalExceptionHandler.getExceptionToString(e));
            throw new ApiException(e);
        }
    }


    @Override
    public Map appRecharge(UnifiedOrderPhoneRequest request, UsersResponse usersResponse) {
        PhoneRechargeConfig phoneRechargeConfig = phoneRechargeConfigMapper.selectByPrimaryKey(request.getRechargeId());
        // 生成支付订单
        PhoneRecharge phoneRecharge = new PhoneRecharge();
        String resOrderNo = OrderUtils.getPhoneOrderCode();
        phoneRecharge.setOrderNo(resOrderNo);
        phoneRecharge.setPhone(request.getPhone());
        phoneRecharge.setOperators(request.getOperators());
        phoneRecharge.setPlatform(TokenUtil.getPlatformData());
        phoneRecharge.setChannel(TokenUtil.getChannel());
        phoneRecharge.setUuid(TokenUtil.getToken());
        phoneRecharge.setStatus(1);                         // 支付中
        phoneRecharge.setPayType(PayTypeEnums.wx.name());
        phoneRecharge.setDenomination(phoneRechargeConfig.getDenomination());
        phoneRecharge.setGiveIntegral(phoneRechargeConfig.getGiveIntegral());
        phoneRecharge.setPrice(phoneRechargeConfig.getPrice());
        phoneRecharge.setErrorStatus(0);
        phoneRecharge.setCreateTime(new Date());
        phoneRecharge.setType("APP-" + request.getType());
        phoneRechargeMapper.insert(phoneRecharge);

        return unifiedPay(resOrderNo, phoneRecharge.getDenomination() + "", request.getOpenid(), request.getType());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String wxAppRechargePayBack(String resXml) {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(CompanyConstant.PLATFORM, WxAppServiceImpl.TYPE, WxAppServiceImpl.TRADE_TYPE);
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);
        WXPay wxpay = new WXPay(myWxConfig);
        return this.handlePhoneOrderBack(wxpay, resXml, WxAppServiceImpl.TYPE);
    }

    @Override
    public void rechargeUpdate() {
        PhoneRechargeExample phoneRechargeExample = new PhoneRechargeExample();
        phoneRechargeExample.createCriteria()
                .andStatusEqualTo(1);
        List<PhoneRecharge> phoneRecharges = phoneRechargeMapper.selectByExample(phoneRechargeExample);
        phoneRecharges.stream().forEach(item -> {
            try {
                Map<String, String> map = wxServiceMap.get("H5-MWEB").wxOrderQuery(item.getOrderNo());
                log.info("订单查询结果：{}", JSONObject.toJSONString(map));
                if ("SUCCESS".equals(map.get("return_code"))) {
                    if ("SUCCESS".equals(map.get("result_code"))) {
                        // 成功
                        if ("SUCCESS".equals(map.get("trade_state"))) {
                            // 更新订单信息
                            PhoneRecharge phoneRecharge = new PhoneRecharge();
                            phoneRecharge.setPayCallback(JSONObject.toJSONString(map));
                            phoneRecharge.setPayCallbackTime(new Date());
                            phoneRecharge.setStatus(3);
                            PhoneRechargeExample example = new PhoneRechargeExample();
                            example.createCriteria()
                                    .andOrderNoEqualTo(item.getOrderNo());
                            phoneRechargeMapper.updateByExampleSelective(phoneRecharge, example);

                            // 修改积分
                            try {
                                String usesInfo = redisService.get(item.getUuid());
                                UsersResponse usersResponse = JSONObject.parseObject(usesInfo, UsersResponse.class);
                                usersResponse.setScore(usersResponse.getScore() + item.getGiveIntegral());
                                redisService.set(usersResponse.getToken(), JSONObject.toJSONString(usersResponse));
                                redisService.expire(usersResponse.getToken(), TokenConstants.EXPIRE_SECONDS);
                            } catch (Exception e) {
                                log.error("加积分异常：{}", item.getOrderNo());
                            }

                            PrepaidRefillDto prepaidRefillDto = new PrepaidRefillDto();
                            prepaidRefillDto.setOrderNo(item.getOrderNo());
                            prepaidRefillDto.setOperators(item.getOperators());
                            // 发送队列
                            rabbitTemplate.convertAndSend(QueueConstants.RECHARGE_QUEUE, prepaidRefillDto);
                        }
                    }
                }
            } catch (Exception e) {
                log.error("异常订单：{}", item.getOrderNo());
                e.printStackTrace();
            }

        });
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String wxAppletRechargePayBack(String resXml) {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(CompanyConstant.PLATFORM, WxAppJsApiServiceImpl.TYPE, WxAppJsApiServiceImpl.TRADE_TYPE);
        MyWxConfig myWxConfig = new MyWxConfig(payConfig);
        WXPay wxpay = new WXPay(myWxConfig);
        return this.handlePhoneOrderBack(wxpay, resXml, WxAppJsApiServiceImpl.TYPE);
    }

    @Transactional(rollbackFor = Exception.class)
    public Integer fullDeduction(UnifiedOrderRequest request, Orders orders, DefaultAddressDto address) {
//        log.info("开始全局事务，XID = " + RootContext.getXID());
//        Orders orders = ordersMapper.selectByPrimaryKey(request.getOrderId());
        BigDecimal realTotalMoney = orders.getRealTotalMoney();
        // 直接修改订单状态
        orders.setOrderRemarks(request.getDesc());
        orders.setIsAnonymity(request.getIsAnonymity());
        orders.setPayType(OrderPayTypeEnums.deduction.name());
        orders.setIsPay(IsPayConstant.YES);
        orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
        orders.setRealTotalMoney(BigDecimal.ZERO);
        orders.setDeductionMoney(realTotalMoney);
        orders.setPayTime(new Date());
        if (request.getAddressId() != null) {
//            DefaultAddressDto address = usersClient.getOneAddress(orders.getUserId(), request.getAddressId());
            orders.setProvince(address.getProvince());
            orders.setCity(address.getCity());
            orders.setAddress(address.getAddress());
            orders.setArea(address.getArea());
            orders.setUserAddress(address.getProvince() + address.getCity() + address.getArea() + address.getAddress());
            orders.setUserName(address.getName());
            orders.setUserPhone(address.getTel());
        }
        orders.setRealNameId(request.getRealNameId());
        ordersMapper.updateByPrimaryKeySelective(orders);
        UserBalanceDto userBalanceDto = new UserBalanceDto();
        userBalanceDto.setUserId(orders.getUserId());
        userBalanceDto.setUpdateMoney(realTotalMoney);
        userBalanceDto.setType("SUB");
        userBalanceDto.setSource(UserBalanceSourceEnums.DEDUCTION.name());
        userBalanceDto.setAmountType(1);
        userBalanceDto.setCode(String.valueOf(orders.getId()));
        usersClient.updateMoney(userBalanceDto);

        // 获取订单明细
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria()
                .andOrderIdEqualTo(orders.getId());
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        ordersInfoList.stream()
                .forEach(item -> {
                    // 修改订单详情状态
                    OrdersInfo ordersInfo = new OrdersInfo();
                    ordersInfo.setId(item.getId());
                    ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                    ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                    try {
                        if ("h5".equals(TokenUtil.getPlatformData())) {
                            String tokenUser = redisService.get(orders.getH5Token());
                            // 商品 减库存 加销量 店家加销量
                            productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(), tokenUser, item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), orders.getUserId());
                        } else {
                            // 商品 减库存 加销量 店家加销量
                            productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(), item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), orders.getUserId());
                        }
                    } catch (Exception e) {
                        log.error(GlobalExceptionHandler.getExceptionToString(e));
                        log.error("减库存发生异常 订单id :{}", item.getId());
                    }
                    if ("h5".equals(TokenUtil.getPlatformData())) {
                        // 删除补贴价格
                        if ("OLD_FOR_NEW".equals(item.getActivityType())) {
                            String key = RedisConstants.SUBSIDYKEY + orders.getH5Token();
                            String subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                            if (StringUtils.isNotEmpty(subsidyObj)) {
                                redisService.delete(key, item.getProductId().toString());
                                this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, orders.getH5Token());
                            }
                        }
                        // 扣除用户的红包余额
                        if ("CASH_COUPON".equals(item.getActivityType())) {
                            this.addUsedActivityMax(item.getActivityMax(), RedisConstants.RETURN_COUPON + orders.getH5Token());//记录用户使用红包金额
                        }
                        //
                        if ("RETURN_COUPON".equals(item.getActivityType())) {
                            this.addReturnCoupon(item.getActivityMax(), RedisConstants.RETURN_COUPON + orders.getH5Token());//记录用户返现红包金额
                        }
                    } else {
                        try {
                            // 删除补贴价格
                            if ("OLD_FOR_NEW".equals(item.getActivityType())) {
                                String key = RedisConstants.SUBSIDYKEY_APP + orders.getH5Token();
                                if ("APP".equals(TokenUtil.getPlatformData().toUpperCase())) {
                                    this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY_APP, orders.getH5Token(), orders.getUserId());
                                } else {
                                    String subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                                    if (StringUtils.isNotEmpty(subsidyObj)) {
                                        redisService.delete(key, item.getProductId().toString());
                                        this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY_APP, orders.getH5Token());
                                    }
                                }
                            }
                            // 扣除用户的红包余额
                            if ("CASH_COUPON".equals(item.getActivityType())) {
                                this.addUsedActivityMax(item.getActivityMax(), RedisConstants.RETURN_COUPON_APP + orders.getH5Token());//记录用户使用红包金额
                            }
                            //
                            if ("RETURN_COUPON".equals(item.getActivityType())) {
                                this.addReturnCoupon(item.getActivityMax(), RedisConstants.RETURN_COUPON_APP + orders.getH5Token());//记录用户返现红包金额
                            }
                        } catch (Exception e) {
                        }
                    }

                });
        return orders.getId();
    }

    @Override
    public long helpWorkNum(Integer userId) {
        HelpWorkExample example = new HelpWorkExample();
        example.createCriteria().andUserIdEqualTo(userId).andStatusEqualTo(1);
        long count = helpWorkMapper.countByExample(example);
        if (count >= 3) {
            return count;
        }
        HelpWorkExample helpWorkExample = new HelpWorkExample();
        helpWorkExample.createCriteria().andUserIdEqualTo(userId).andStatusEqualTo(3);
        //助力已完成未支付的数量
        List<HelpWork> helpWorks = helpWorkMapper.selectByExample(helpWorkExample);
        if (helpWorks.size() == 0) {
            return count;
        }
        AtomicLong count1 = new AtomicLong();
        helpWorks.forEach(item -> {
            OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(item.getOrderInfoId());
            if (null != ordersInfo && ordersInfo.getOrderinfoStatus().equals("0")) {
                count1.set(count1.get() + 1);
            }
        });
        return count + count1.get();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult cancelOrder(String orderNo) {
        //修改订单状态为已关闭
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andOrderNoEqualTo(orderNo);
        List<Orders> ordersList = ordersMapper.selectByExample(ordersExample);
        if (CollectionUtils.isEmpty(ordersList)) {
            throw new ApiException("订单信息异常");
        }
        Orders orders = ordersList.get(0);
        if (!orders.getOrderStatus().equals(OrderStatusEnums.OBLIGATION.getValue())) {
            throw new ApiException("该订单不为待付款,不能关闭订单");
        }
        orders.setOrderStatus(OrderStatusEnums.CLOSED.getValue());
        orders.setOrderRemarks("订单未支付,已手动取消");
        ordersMapper.updateByPrimaryKeySelective(orders);
        //修改订单详情为已关闭
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(orders.getId());
        List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
        if (CollectionUtils.isEmpty(ordersInfos)) {
            return CommonResult.success();
        }
        ordersInfos.stream().forEach(item -> {
            item.setCloseRemarks("订单未支付,已手动取消");
            item.setOrderinfoStatus(OrderStatusEnums.CLOSED.getValue());
            ordersInfoMapper.updateByPrimaryKeySelective(item);
            Product product = productMapper.selectByPrimaryKey(item.getProductId());
            //一分兑 减少兑换次数
            if (product.getActivityType().equals(ActivityTypeEnums.PENNY_CONVERSION)) {
                String s = redisService.get(com.ytjj.common.constants.RedisConstants.GUOB_H5_SIGN_CONVERSION + TokenUtil.getToken());
                if (StringUtils.isNotBlank(s)) {
                    int i = Integer.parseInt(s);
                    int count = i + 1;
                    redisService.set(com.ytjj.common.constants.RedisConstants.GUOB_H5_SIGN_CONVERSION + TokenUtil.getToken(), Integer.toString(count));
                }
            }
            //库存解冻
            try {
                //更新库存冻结状态(调用这个方法后 还需要调用下面的subAndAddStock方法)
                updateProductStock(item.getChildOrderNo(), 4);
            } catch (Exception e) {
                log.error("========更新库存冻结状态===库存解冻=====item.getChildOrderNo()====={}", item.getChildOrderNo());
            }

        });
        return CommonResult.success("取消订单成功");
    }

    @Override
    public CommonResult deleteOrder(Integer orderInfoId) {
        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(orderInfoId);
        if (null == ordersInfo) {
            throw new ApiException("订单信息异常");
        }
        Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());
        if (orders.getIsPay() == 1) {
            if (ordersInfo.getOrderinfoStatus().equals("3") || ordersInfo.getOrderinfoStatus().equals("4") || ordersInfo.getOrderinfoStatus().equals("5")) {
                ordersInfo.setId(orderInfoId);
                ordersInfo.setIsDelete(1);
                ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                return CommonResult.success("删除订单成功");
            }
        } else {
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(ordersInfo.getOrderId());
            List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
            ordersInfos.stream().forEach(item -> {
                item.setId(item.getId());
                item.setIsDelete(1);
                ordersInfoMapper.updateByPrimaryKeySelective(item);
            });
            return CommonResult.success("删除订单成功");
        }

        return CommonResult.success("删除订单失败");
    }

    /**
     * 订单上传接口--上传到供应链
     * @param orderId 主订单id
     * @param transferId 转单id，存值在则是来自手动转单
     */
    @Override
    public void ordersUpload(Integer orderId,Integer transferId) {
        log.info("===========准备推送订单到供应链============orderId:{}", orderId);
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        log.info("===========准备推送订单到供应链============orders:{}", JSONObject.toJSONString(orders));
        if (orders.getIsPay() != 1) {
            return;
        }
        OrdersPay ordersPay = ordersPayMapper.findOrdersPayByOrderNo(orders.getOrderNo());
        log.info("===========准备推送订单到供应链============ordersPay:{}", JSONObject.toJSONString(ordersPay));
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(orderId).andOrderinfoStatusEqualTo("1");
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        List<OrderUploadRequest> orderUploadRequestList = new ArrayList<>();
        log.info("===orders.realNameId==={}", orders.getRealNameId());
        UsersRealName usersRealName = usersRealNameMapper.selectByPrimaryKey(orders.getRealNameId());
        //转单任务集合
        List<OrdersTransferManage> ordersTransferManages = new ArrayList<>();
        if(transferId != null){
            OrdersTransferManage ordersTransferManage = ordersTransferManageMapper.selectByPrimaryKey(transferId);
            //任务不存在或者被删除，则不同步订单
            if(ordersTransferManage == null || ordersTransferManage.getIsDeleted() == 1){
                return;
            }
            ordersTransferManages.add(ordersTransferManage);
        }else {
            OrdersTransferManageExample traManExample = new OrdersTransferManageExample();
            traManExample.createCriteria().andStatusEqualTo(1).andIsDeletedEqualTo(0);
            ordersTransferManages = ordersTransferManageMapper.selectByExampleWithBLOBs(traManExample);
        }
        Map<Integer, List<OrdersTransferManage>> tManageMap = new HashMap<>();
        if(!CollectionUtils.isEmpty(ordersTransferManages)){
            tManageMap = ordersTransferManages.stream().collect(Collectors.groupingBy(e -> e.getOrangeProductId()));
        }
        Map<Integer, List<OrdersTransferManage>> finalTManageMap = tManageMap;
        //转单前的订单集合
        List<OrdersInfo> orangeOrdersInfos = new ArrayList<>();
        //修改后的转单集合
        List<OrdersInfo> modifyOrdersInfos = new ArrayList<>();
        ordersInfoList.stream().forEach(ordersInfo -> {
            log.info("====当前手动转单id{}==",transferId);
            //转单逻辑
            List<OrdersTransferManage> ordersTransferList = finalTManageMap.get(ordersInfo.getProductId());
            //存在当前商品的转单计划
            if(!CollectionUtils.isEmpty(ordersTransferList)){
                try {
                    log.info("====进入了转单逻辑==",transferId);
                    OrdersInfo newEntity = new OrdersInfo();
                    BeanUtils.copyProperties(ordersInfo,newEntity);
                    orangeOrdersInfos.add(newEntity);
                    OrdersInfo modifyMark = modifyOrders(ordersInfo, ordersTransferList,transferId);
                    if(null != modifyMark){
                        modifyOrdersInfos.add(modifyMark);
                        ordersInfo = modifyMark;
                    }else if(null != transferId && modifyMark == null) {
                        log.info("====跳出，不符合转单{}==",transferId);
                        return;
                    }
                } catch (Exception e) {
                    log.error(String.format("======订单:%s 转单失败,当前转单任务:%s======", ordersInfo.getChildOrderNo(), JSON.toJSONString(ordersTransferList)), e);
                    FeiShuUtil.sendMsg("=======订单：" + ordersInfo.getChildOrderNo() + "转单到任务:" + JSON.toJSONString(ordersTransferList) + "失败！========" + e.getMessage());
                }
            }
            log.info("===========准备推送订单到供应链============childOrderNo:{}", ordersInfo.getChildOrderNo());
            Product product = productMapper.selectByPrimaryKey(ordersInfo.getProductId());
            //如果购买的商品活动为补签卡,增加用户补签次数
            if (product.getActivityType().equals(ActivityTypeEnums.RETROACTIVE_CARD)) {
                Users users = usersMapper.selectByPrimaryKey(orders.getUserId());
                redisService.increment(com.ytjj.common.constants.RedisConstants.GUOB_H5_RETROACTIVE_NUM + users.getToken(), 1);

            }
            log.info("====逻辑111：==");
            ProductSpec productSpec = productSpecMapper.selectByPrimaryKey(ordersInfo.getProductSpecId());
            OrdersInfoFreightDto dto = ordersDao.selectFreightByChildOrderNo(ordersInfo.getChildOrderNo());
            OrderUploadRequest orderUploadRequest = new OrderUploadRequest();
            orderUploadRequest.setAccount(orders.getAccount());
            orderUploadRequest.setFreight(null != dto ? dto.getFreight() : BigDecimal.valueOf(0));//运费
            orderUploadRequest.setFreightId(null != dto ? dto.getFreightId() : null);//运费模板id
            orderUploadRequest.setBankerId(product.getBankerId());
            orderUploadRequest.setCostPrice(ordersInfo.getCostPrice());
            orderUploadRequest.setChildOrderNo(ordersInfo.getChildOrderNo());
            orderUploadRequest.setDeliveryAddress(orders.getUserAddress());
            orderUploadRequest.setNote(ordersInfo.getServiceRemark());
            orderUploadRequest.setOrderDate(orders.getCreateTime());
            orderUploadRequest.setPayDate(orders.getPayTime());
            orderUploadRequest.setOrderInfoId(ordersInfo.getId());
            orderUploadRequest.setUserName(orders.getUserName());
            orderUploadRequest.setUserTel(orders.getUserPhone());
            orderUploadRequest.setProductName(ordersInfo.getProductName() + "(" + ordersInfo.getProductSkuSpec() + ")");
            orderUploadRequest.setProductImg(ordersInfo.getProductImg());
            orderUploadRequest.setProductPrice(ordersInfo.getProductPrice());
            orderUploadRequest.setProductSum(ordersInfo.getProductSum());
            orderUploadRequest.setProductId(product.getSupplyProductId());
            orderUploadRequest.setProductSpecId(productSpec.getSupplyId());//供应链的规格id
            orderUploadRequest.setProductSkuSpec(ordersInfo.getProductSkuSpec());
            orderUploadRequest.setSmallNote(orders.getOrderRemarks());
            orderUploadRequest.setShopId(supplyApiConfig.getShopId());
            orderUploadRequest.setIsExit(product.getIsExit());
            orderUploadRequest.setProvince(orders.getProvince());
            orderUploadRequest.setCity(orders.getCity());
            orderUploadRequest.setArea(orders.getArea());
            orderUploadRequest.setIsZeroProduct(product.getIsZeroProduct());
            orderUploadRequest.setThreeSkuId(ordersInfo.getThreeSkuId());
            //经销商id
            orderUploadRequest.setServiceId(serviceId);
            //商城支付金额
            orderUploadRequest.setPayPrice(ordersInfo.getProductPrice());
            //主订单的钱包抵扣金额
            BigDecimal deductionMoney = orders.getDeductionMoney();
            //钱包抵扣金额

            try {
                if (null != deductionMoney && ordersInfoList.size() == 1){
                    orderUploadRequest.setDeductionPrice(deductionMoney);
                }else {
                    orderUploadRequest.setDeductionPrice(null != deductionMoney ? deductionMoney.multiply(ordersInfo.getProductPrice().divide(orders.getRealTotalMoney(),10,BigDecimal.ROUND_HALF_UP).setScale(2,BigDecimal.ROUND_HALF_UP)):null);
                }
            } catch (Exception e) {
                log.error("计算钱包抵扣金额错误");
            }
            if (null != ordersPay) {
                OrdersPayDTO ordersPayDTO = new OrdersPayDTO();
                BeanUtils.copyProperties(ordersPay, ordersPayDTO);
                orderUploadRequest.setOrdersPayDTO(ordersPayDTO);
            }
            if (null != usersRealName) {
                orderUploadRequest.setAuthenticatedName(usersRealName.getName());
                orderUploadRequest.setAuthenticatedCard(usersRealName.getCard());
            }
            log.info("====进入最后逻辑判断==",JSON.toJSONString(orderUploadRequest));
            orderUploadRequestList.add(orderUploadRequest);

        });
        String json = JSON.toJSONString(orderUploadRequestList);
        log.info("========上传供应链参数========={}", json);
        String resultJson = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/upload", json, supplyApiConfig.getHeadsMap());
        CommonResult commonResult = JSONObject.parseObject(resultJson, CommonResult.class);
        log.info("======上传订单response：{}",resultJson);
        if (commonResult != null && 200 == commonResult.getCode()) {
            //订单推送成功的订单集合
            List<String> successChildOrderList = JSONArray.parseArray(JSON.toJSONString(commonResult.getData()),String.class);
            Map<String,OrdersInfo> orangeOrdersInfoMap = new HashMap<>();
            for (OrdersInfo orangeOrdersInfo : orangeOrdersInfos) {
                orangeOrdersInfoMap.put(orangeOrdersInfo.getChildOrderNo(), orangeOrdersInfo);
            }
            for (OrdersInfo targetOrdersInfo : modifyOrdersInfos) {
                boolean b = successChildOrderList.stream().anyMatch(e -> e.equals(targetOrdersInfo.getChildOrderNo()));
                if(b){//供应链已更新，销售端订单需要将此单更新转单
                    OrdersInfo orangeOrdersInfo = orangeOrdersInfoMap.get(targetOrdersInfo.getChildOrderNo());
                    if (null == orangeOrdersInfo) {
                        FeiShuUtil.sendMsg("====转单错误。已转单给供应链，但销售端订单状态修改失败！请修复数据====子订单号：" + targetOrdersInfo.getChildOrderNo());
                        continue;
                    }
                    doTransferOrders(orangeOrdersInfo,targetOrdersInfo);
                }
            }
        }else {
            log.info("===========推送订单到供应链失败============orderId:{}", orderId);
            throw new ApiException("==========订单上传供应链失败"+JSON.toJSONString(commonResult));
        }
    }

    /**
     * 修改库存
     * @param product
     * @param productSpec
     * @param num
     * @param type 更新类型 sub-扣减 add-增加
     * @return void
     */
    public void modifyStock(Product product,ProductSpec productSpec,Integer num,String type){
        Map<String, String> map = new LinkedMap();
        map.put("productId", String.valueOf(product.getSupplyProductId()));
        map.put("num", String.valueOf(num));
        map.put("productSpecId", String.valueOf(productSpec.getSupplyId()));
        map.put("type", type);
        HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/stock/subAndAddStockForTransfer", map, supplyApiConfig.getHeadsMap());
    }

    /**
     * 修改订单
     */
    public OrdersInfo modifyOrders(OrdersInfo ordersInfo,List<OrdersTransferManage> transferManages,Integer transferId){
        OrdersInfo resultData = null;
        for (OrdersTransferManage transferManage : transferManages) {
            List<OrdersTransferManage> ordersTransferManages = new ArrayList<>();
            if (null != transferId) {
                OrdersTransferManage tm =  ordersTransferManageMapper.selectByPrimaryKey(transferId);
                //手动转单，任务不存在或被删除
                if(null == tm || tm.getIsDeleted() == 1){
                    break;
                }
                ordersTransferManages.add(tm);
            } else {
                //再次查询转单任务,防止被停用
                OrdersTransferManageExample traManExample = new OrdersTransferManageExample();
                traManExample.createCriteria().andStatusEqualTo(1).andIsDeletedEqualTo(0).andOrangeProductIdEqualTo(ordersInfo.getProductId());
                ordersTransferManages = ordersTransferManageMapper.selectByExampleWithBLOBs(traManExample);
            }
            //当前商品没有转单任务
            if(CollectionUtils.isEmpty(ordersTransferManages)){
                break;
            } else {
                boolean isContain = ordersTransferManages.stream().anyMatch(e -> e.getId().equals(transferManage.getId()));
                //当前转单任务不存在
                if(!isContain){
                    continue;
                }
            }
            Integer todayCount = ordersTransferLogDao.getCountByToday(ordersInfo.getProductId(),transferManage.getTargetProductId());
            //当前已转订单数超过设置值
            if (null != transferManage.getTransferNum() && todayCount >= transferManage.getTransferNum()) {
                continue;
            }
            //当前订单商品规格
            List<ProductSpec> orgSpecs = JSON.parseArray(transferManage.getOrangeProductSpec(), ProductSpec.class);
            int index = -1;
            for (int i = 0; i < orgSpecs.size(); i++) {
                if(ordersInfo.getProductSpecId().equals(orgSpecs.get(i).getId())){
                    index = i;
                    break;
                }
            }
            if(index == -1){
                FeiShuUtil.sendMsg(String.format("转单失败，将按照原供应商推单。当前订单:%s商品的规格id:%s 匹配不到对应的转单商品规格，请及时修改！",ordersInfo.getChildOrderNo(),ordersInfo.getProductSpecId()));
                continue;
            }
            //当前商品对应的转单商品的规格
            List<ProductSpec> tagSpecs = JSON.parseArray(transferManage.getTargetProductSpec(), ProductSpec.class);
            //规格不是一一对应，则跳过，不转单
            if (index > tagSpecs.size() - 1) {
                continue;
            }
            ProductSpec tagSpec = tagSpecs.get(index);
            //最新转单商品规格
            ProductSpec tagSpecEntity = productSpecMapper.selectByPrimaryKey(tagSpec.getId());
            //规格可能被修改，按原供应商推单
            if(null == tagSpecEntity){
                FeiShuUtil.sendMsg(String.format("转单失败，将按照原供应商推单。原因：转单商品规格不存在，请及时修改! 订单%s,转单商品规格id:%s",ordersInfo.getChildOrderNo(),tagSpec.getId()));
                continue;
            }
            //转单商品
            Product product = productMapper.selectByPrimaryKey(transferManage.getTargetProductId());
            //转单的商品不是上架状态不能转单
            if(Integer.valueOf(product.getStatus()) != 1){
                FeiShuUtil.sendMsg(String.format("转单失败，将按照原供应商推单。原因：转单商品不是上架状态，请及时停用或修改转单计划! 订单%s,转单计划id:%s",transferManage.getId()));
                continue;
            }
            ordersInfo.setId(ordersInfo.getId());
            ordersInfo.setProductId(product.getId());
            ordersInfo.setBankerId(product.getBankerId());
            ordersInfo.setProductSpecId(tagSpecEntity.getId());
            ordersInfo.setProductSkuSpec(tagSpecEntity.getSkuSpec());
            ordersInfo.setProductImg(product.getProductImg());
            ordersInfo.setProductName(product.getProductName());
            ordersInfo.setWarehouse(product.getWarehouse());
            ordersInfo.setWarehouseName(product.getWarehouseName());
            ordersInfo.setDescr(product.getDescr());
            resultData = ordersInfo;

            //设置转单后的商品统计信息,防止新统计数据不准
            try {
                pools.execute(() -> {
                    setBasicDataToMongo(ordersInfo,product);
                });
            } catch (Exception e) {
                log.error("异步将转单后的商品统计信息保存到mongo出错！{}", e);
            }
            break;
        }
        return resultData;
    }

    /**
     * 设置转单后的商品统计信息,防止新统计数据不准
     */
    public void setBasicDataToMongo(OrdersInfo ordersInfo,Product product){
        //查询主订单
        Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());
        ProductStatisticsDto productStatisticsDto = new ProductStatisticsDto();
        productStatisticsDto.setUuid(orders == null ? "" : orders.getH5Token());
        productStatisticsDto.setPlatform(orders.getOrderSource());
        productStatisticsDto.setIp("127.0.0.1");
        productStatisticsDto.setChannel(orders.getChannel());
        productStatisticsDto.setActivityType(product.getActivityType());
        productStatisticsDto.setIsActivity(product.getProductType());
        productStatisticsDto.setProductId(product.getId());
        productStatisticsDto.setProductName(product.getProductName());
        productStatisticsDto.setBankerId(product.getBankerId());
        productStatisticsDto.setCreateTime(orders.getCreateTime());
        productStatisticsDto.setScene(StringUtils.isEmpty(ordersInfo.getScene()) ? "" : ordersInfo.getScene());
        //设置推广账号
        try {
            OrdersPayExample ordersPayExample = new OrdersPayExample();
            ordersPayExample.createCriteria().andOrderNoEqualTo(orders.getOrderNo()).andPayTypeEqualTo(com.ytjj.common.enums.PayPayTypeEnums.SUCCEED.getType());
            List<OrdersPay> ordersPays = ordersPayMapper.selectByExample(ordersPayExample);
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(ordersPays)){
                OrdersPay pay = ordersPays.get(0);
                if (pay!=null && pay.getChildId()!=null){
                    productStatisticsDto.setAccount("");
                }
            }
        } catch (Exception e) {
            log.error("转单设置推广账号出错,{}",e);
        }
        rabbitTemplate.convertAndSend(QueueConstants.PRODUCT_STATISTICS_QUEUE,productStatisticsDto);
    }

    /**
     * 订单转单,修改订单数据
     */
    public void doTransferOrders(OrdersInfo orangeOrdersInfo, OrdersInfo targetOrdersInfo) {

        //更新订单转单数据
        OrdersInfo newEntity = new OrdersInfo();
        newEntity.setId(targetOrdersInfo.getId());
        newEntity.setProductId(targetOrdersInfo.getProductId());
        newEntity.setProductName(targetOrdersInfo.getProductName());
        newEntity.setBankerId(targetOrdersInfo.getBankerId());
        newEntity.setProductImg(targetOrdersInfo.getProductImg());
        newEntity.setWarehouseName(targetOrdersInfo.getWarehouseName());
        newEntity.setWarehouse(targetOrdersInfo.getWarehouse());
        newEntity.setProductSpecId(targetOrdersInfo.getProductSpecId());
        newEntity.setProductSkuSpec(targetOrdersInfo.getProductSkuSpec());
        newEntity.setDescr(targetOrdersInfo.getDescr());
        newEntity.setUpdateTime(new Date());
        ordersInfoMapper.updateByPrimaryKeySelective(newEntity);
        //记录转单日志
        OrdersTransferLog ordersTransferLog = new OrdersTransferLog();
        ordersTransferLog.setOrangeBankerId(orangeOrdersInfo.getBankerId());
        ordersTransferLog.setOrangeProductId(orangeOrdersInfo.getProductId());
        ordersTransferLog.setOrangeProductSpecId(orangeOrdersInfo.getProductSpecId());
        ordersTransferLog.setOrangeJson(JSON.toJSONString(orangeOrdersInfo));
        OrdersTransferLogExample ordersTransferLogExample = new OrdersTransferLogExample();
        ordersTransferLogExample.createCriteria().andChildOrderNoEqualTo(orangeOrdersInfo.getChildOrderNo());
        List<OrdersTransferLog> ordersTransferLogs = ordersTransferLogMapper.selectByExample(ordersTransferLogExample);
        if (CollectionUtils.isEmpty(ordersTransferLogs)) {
            ordersTransferLog.setChildOrderNo(orangeOrdersInfo.getChildOrderNo());
            ordersTransferLog.setCreateTime(new Date());
            ordersTransferLog.setTargetProductId(targetOrdersInfo.getProductId());
            ordersTransferLog.setTargetBankerId(targetOrdersInfo.getBankerId());
            ordersTransferLog.setTargetProductSpecId(targetOrdersInfo.getProductSpecId());
            ordersTransferLogMapper.insert(ordersTransferLog);
        }

        //处理商品库存
        ProductExample productExample = new ProductExample();
        productExample.createCriteria().andIdIn(Arrays.asList(orangeOrdersInfo.getProductId(),targetOrdersInfo.getProductId()));
        List<Product> product = productMapper.selectByExample(productExample);
        ProductSpecExample example = new ProductSpecExample();
        example.createCriteria().andIdIn(Arrays.asList(orangeOrdersInfo.getProductSpecId(),targetOrdersInfo.getProductSpecId()));
        List<ProductSpec> productSpec = productSpecMapper.selectByExample(example);
        //原商品信息
        List<Product> orangeProducts = product.stream().filter(e -> e.getId().equals(orangeOrdersInfo.getProductId())).collect(Collectors.toList());
        List<ProductSpec> orangeSpecs = productSpec.stream().filter(e -> e.getId().equals(orangeOrdersInfo.getProductSpecId())).collect(Collectors.toList());
        //目标商品信息
        List<Product> targetProducts = product.stream().filter(e -> e.getId().equals(targetOrdersInfo.getProductId())).collect(Collectors.toList());
        List<ProductSpec> targetSpecs = productSpec.stream().filter(e -> e.getId().equals(targetOrdersInfo.getProductSpecId())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(orangeProducts) && !CollectionUtils.isEmpty(orangeSpecs)){
            modifyStock(orangeProducts.get(0),orangeSpecs.get(0),orangeOrdersInfo.getProductSum(),"add");
        }
        if (!CollectionUtils.isEmpty(targetProducts) && !CollectionUtils.isEmpty(targetSpecs)) {
            modifyStock(targetProducts.get(0), targetSpecs.get(0), orangeOrdersInfo.getProductSum(), "sub");
        }
    }
    /**
     * 冻结库存前查一下库存是否足够用
     *
     * @param productId
     * @param productSpecId
     * @return true--库存充足
     */
    @Override
    public boolean checkProductStock(Integer productId, Integer productSpecId, Integer productSum) {
        Product product = productMapper.selectByPrimaryKey(productId);
        if (null == product) {
            return false;
        }
        ProductSpec productSpec = productSpecMapper.selectByPrimaryKey(productSpecId);
        Map<String, String> map = new LinkedMap();
        map.put("bankerProductId", String.valueOf(product.getBankerProductId()));
        map.put("supplyId", String.valueOf(productSpec.getSupplyId()));
        log.info("=============/stock/get=====================参数{}", map);
        String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/stock/get", map, supplyApiConfig.getHeadsMap());
        log.info("=============/stock/get=====================返回{}", resultJson);
        if (org.springframework.util.StringUtils.isEmpty(resultJson)) {
            return false;
        }
        CommonResult commonResult = JSONObject.parseObject(resultJson, CommonResult.class);

        if (200 != commonResult.getCode()) {
            throw new ApiException("商品信息异常");
        }
        ProductStockAndSpecResponse response = JSONObject.parseObject(commonResult.getData().toString(), ProductStockAndSpecResponse.class);

        try{
            if (null != response.getStockWarning() && null != response.getStock() && response.getStockWarning()>=response.getStock()) {
                String key = RedisConstants.STOCK_WARNING+product.getId();
                String warningFlag = redisService.get(key);
                if (StringUtils.isBlank(warningFlag)) {
                    FeiShuUtil.sendYxMsg("供应商商品id为: "+response.getProductId()+"的商品===="+response.getProductName()+"===库存即将不足,请补充货源！！！");
                    redisService.set(key,"1",60*2);
                }
            }
        }catch (Exception e) {
            log.info("发送库存预警警告报错:{}",e.getMessage());
        }

        log.info("===response==={}", response);
        if (response.getStatus() != 1) {
            throw new ApiException("库存不足，请稍后再来");
        }
        if (null == productSum) {
            productSum = 1;
        }
        if (null != response.getStock() && response.getStock() >= productSum && null != response.getSpecStock() && response.getSpecStock() >= productSum) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 下单时冻结库存
     *
     * @param orderId
     */
    @Async
    @Override
    public void ProductStockFrozen(Integer orderId) {
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(orderId);
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        ordersInfoList.stream().forEach(ordersInfo -> {
            Product product = productMapper.selectByPrimaryKey(ordersInfo.getProductId());
            ProductSpec productSpec = productSpecMapper.selectByPrimaryKey(ordersInfo.getProductSpecId());

            ProductStockFrozenRequest productStockFrozenRequest = new ProductStockFrozenRequest();
            productStockFrozenRequest.setNum(null == ordersInfo.getProductSum() ? 1 : ordersInfo.getProductSum());
            productStockFrozenRequest.setChildOrderNo(ordersInfo.getChildOrderNo());
            productStockFrozenRequest.setProductId(product.getBankerProductId());//取供应商商品id
            productStockFrozenRequest.setProductSpecId(productSpec.getSupplyId());//取供应链的规格id
            productStockFrozenRequest.setShopId(supplyApiConfig.getShopId());
            String json = JSON.toJSONString(productStockFrozenRequest);
            log.info("=======ProductStockFrozen==========={}", json);
            HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/stock/frozen", json, supplyApiConfig.getHeadsMap());
        });
    }

    /**
     * 更新库存冻结状态(调用这个方法后 还需要调用下面的subAndAddStock方法)
     *
     * @param orderNo 订单编号
     * @param status  更新状态值 2-已扣库存 3-退还库存 4-冻结作废(超时未支付或取消支付)
     */
    public void updateProductStock(String orderNo, Integer status) {

        Map<String, String> map = new LinkedMap();
        map.put("orderNo", orderNo);
        map.put("status", String.valueOf(status));
        String result = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/stock/updateProductStock", map, supplyApiConfig.getHeadsMap());
        if (!"true".equals(result)) {
            log.info("=======更新库存冻结状态异常========orderNo{}", orderNo);
        }
    }

    /**
     * 扣减或退还库存
     *
     * @param num  商品数量
     * @param type sub-扣减 add-退还
     * @return
     */
    public void subAndAddStock(String orderNo, Integer num, Integer isZeroProduct, String type) {
        Map<String, String> map = new LinkedMap();
        map.put("orderNo", orderNo);
        map.put("num", String.valueOf(num));
        map.put("isZeroProduct", String.valueOf(isZeroProduct));
        map.put("type", type);
        log.info("=======调用供应链扣减或退还库存====参数===={}", map);
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/stock/subAndAddStock", map, supplyApiConfig.getHeadsMap());
        log.info("=======调用供应链扣减或退还库存====返回===={}", s);
    }

    /**
     * 获取运费模板
     *
     * @return
     */
    @Override
    public FreightTemplateResponse getFreightTemplateResponse(Integer productId) {
        Product product = productMapper.selectByPrimaryKey(productId);
        Map<String, String> map = new LinkedMap();
        map.put("id", String.valueOf(product.getBankerProductId()));
        String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/product/findFreightTemplateResponse", map, supplyApiConfig.getHeadsMap());
        if (null == resultJson) {
            return null;
        }
        FreightTemplateResponse data = JSONObject.parseObject(resultJson, FreightTemplateResponse.class);
        return data;
    }

    private FreightTemplateResponse getOwnerFreightTemplate(Integer productId){
        Product product = productMapper.selectByPrimaryKey(productId);
        CommonResult<FreightTemplateResponse> commonResult = freightTemplateClient.selectFreightTemplateResponse(product.getFreightId());
        log.info("调用Feign接口查询商品模板: {}", JSONUtil.toJsonStr(commonResult));
        if( null == commonResult.getData() ) {
            commonResult = freightTemplateClient.selectDefaultFreightTemplate(product.getPlatformData());
        }
        return commonResult.getData();
    }

    public FreightTemplateResponse getDefaultFreightTemplate(Integer productId) {
        Product product = productMapper.selectByPrimaryKey(productId);
        CommonResult<FreightTemplateResponse> commonResult = freightTemplateClient.selectDefaultFreightTemplate(product.getPlatformData());
        if (null != commonResult) {
            return commonResult.getData();
        }
        return null;
    }

    /**
     * 微信支付V3回调处理
     *
     * @param type
     * @param data
     * @param signatureHeader
     * @return
     * @throws WxPayException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String wxV3PayBack(String type, String data, SignatureHeader signatureHeader) throws WxPayException {
        String paytype = "";
        String tradeType = "";
        String company="";
        if (WxPayConstant.ISV_TRADE_TYPE_H5.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "MWEB";
            company=WxPayConstant.COMPANY;
        }else if (WxPayConstant.ISV_TRADE_TYPE_JSAPI.equalsIgnoreCase(type)) {
            paytype = "APP";
            tradeType = "JSAPI";
            company=WxPayConstant.COMPANY;
        } else if (WxPayConstant.ISV_PHONE_CHARGES.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "PHONE_CHARGES";
            company=WxPayConstant.COMPANY;
        } else if (WxPayConstant.ISV_TRADE_TYPE_H5_TXG.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "MWEB";
            company=WxPayConstant.COMPANY_TXG;
        } else if (WxPayConstant.ISV_TRADE_TYPE_APP_TXG.equalsIgnoreCase(type)) {
            paytype = "APP";
            tradeType = "APP";
            company=WxPayConstant.COMPANY_TXG;
        } else if (WxPayConstant.ISV_TRADE_TYPE_JSAPI_TXG.equalsIgnoreCase(type)) {
            paytype = "APP";
            tradeType = "JSAPI";
            company=WxPayConstant.COMPANY_TXG;
        } else if (WxPayConstant.TRADE_TYPE_H5_JSAPI.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "JSAPI";
            company=WxPayConstant.NEW_COMPANY;
        } else if (WxPayConstant.TRADE_TYPE_H5_JSAPI2.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "JSAPI2";
            company=WxPayConstant.NEW_COMPANY;
        }else if (WxPayConstant.TRADE_TYPE_H5_MWEB.equals(type)){
            paytype = "H5";
            tradeType = "MWEB";
            company="guchuangh5";
        }else if (WxPayConstant.TRADE_TYPE_H5_MWEB2.equals(type)){
            paytype = "H5";
            tradeType = "MWEB2";
            company="guchuangh5";
        }
        PayConfig payConfig = ordersDao.getPayConfigByCompany(company, paytype, tradeType);
        WxPayService wxPayService = WxPayServiceUtil.getWxPayService(payConfig);
        wxPayService.getConfig().setPrivateKeyPath(payConfig.getPrivateKeyPath());
        wxPayService.getConfig().setCertSerialNo(payConfig.getCertSerialNo());
        wxPayService.getConfig().setApiV3Key(payConfig.getWxKey());
        wxPayService.getConfig().setPrivateCertPath(payConfig.getPrivateCertPath());
        WxPayOrderNotifyV3Result notifyResult = wxPayService.parseOrderNotifyV3Result(data, signatureHeader);

        log.info("====notifyResult:{}", JSONObject.toJSONString(notifyResult));
        String tradeState = notifyResult.getResult().getTradeState();
        if ("SUCCESS".equalsIgnoreCase(tradeState)) {
            WxPayOrderNotifyV3Result.DecryptNotifyResult decryptNotifyResult = notifyResult.getResult();
            decryptNotifyResult.setTradeType(type);
            if ("H5".equals(paytype)) {
                if ("PHONE_CHARGES".equals(tradeType)) {//手机充值
                    this.updateH5ISVPhoneOrderPay(decryptNotifyResult);
                } else {
                    if(WxPayConstant.TRADE_TYPE_H5_JSAPI.equalsIgnoreCase(type)){
                        decryptNotifyResult.setTradeType(WxPayConstant.TRADE_TYPE_JSAPI);
                    }
                    if(WxPayConstant.TRADE_TYPE_H5_JSAPI2.equalsIgnoreCase(type)){
                        decryptNotifyResult.setTradeType(WxPayConstant.TRADE_TYPE_JSAPI2);
                    }

                    if(WxPayConstant.TRADE_TYPE_H5_MWEB.equalsIgnoreCase(type)){
                        decryptNotifyResult.setTradeType("MWEB");
                    }
                    if(WxPayConstant.TRADE_TYPE_H5_MWEB2.equalsIgnoreCase(type)){
                        decryptNotifyResult.setTradeType("MWEB2");
                    }
                    this.updateH5OrderPay(decryptNotifyResult);
                }
            } else {
                this.updateOrderPay(decryptNotifyResult);
            }
            return WxPayNotifyResponse.success("成功");
        } else {
            return WxPayNotifyResponse.fail("失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String adapayPayNotify(HttpServletRequest request, String type) {
        boolean check = adaPayService.checkSign(request);
        String resCode = "200";
        String errorCode = "500";
        if(check){
            String data = request.getParameter("data");
            Map<String,Object> map = JSONObject.parseObject(data, Map.class);
            log.info("adapay 微信小程序支付，回调数据：{}", JSONObject.toJSONString(map));
            // 查询订单是否是处理中
            Object resOrderNo = map.get("order_no");
            OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(resOrderNo.toString());
            if (null == pay || (!pay.getPayType().equals(PayPayTypeEnums.BEING_PROCESSED.getType()) && PayPayTypeEnums.FAIL.getType() != pay.getPayType().byteValue())) {
                return resCode;
            }
            if ("succeeded".equals(map.get("status"))) {

                Map<String,String> expend =(Map) map.get("expend");
                // 更新支付订单信息
                pay.setTradeType(WxPayConstant.H5_ADAPAY_MINI);
                pay.setBankType(expend.get("bank_type"));
                pay.setTotalFee(new BigDecimal(map.get("pay_amt").toString()).multiply(new BigDecimal(100)).intValue());
                pay.setResText(JSONObject.toJSONString(map));
                pay.setPayTime(DateTimeUtil.dealDateFormat(map.get("created_time").toString()));
                pay.setPayType(PayPayTypeEnums.SUCCEED.getType());
                pay.setUpdateTime(new Date());
                ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
                // 更新订单信息
                Orders orders = new Orders();
                orders.setPayType(OrderPayTypeEnums.online_pay.name());
                orders.setPaySource(OrderPaySource.getPaySource(map.get("pay_channel").toString()));
                orders.setIsPay(IsPayConstant.YES);
                orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
                orders.setPayTime(new Date());
                orders.setTradeNo(pay.getResOrderNo());
                OrdersExample example = new OrdersExample();
                example.createCriteria().andOrderNoEqualTo(pay.getOrderNo());
                ordersMapper.updateByExampleSelective(orders, example);
                // 获取订单信息
                Orders order = ordersDao.queryOrdersByOrderNo(pay.getOrderNo());
                //更新redis支付状态
                redisService.set(RedisConstants.ORDER_PAY_INFO+order.getId(),pay.getResOrderNo());
                redisService.expire(RedisConstants.ORDER_PAY_INFO+orders.getId(),60*30);
                // 获取订单明细
                OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
                ordersInfoExample.createCriteria().andOrderIdEqualTo(order.getId());
                List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
                AtomicInteger activityType = new AtomicInteger(0);
                ordersInfoList.stream().forEach(item -> {
                    String tokenUser = redisService.get(order.getH5Token());
                    // 修改订单详情状态
                    OrdersInfo ordersInfo = new OrdersInfo();
                    ordersInfo.setId(item.getId());
                    ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                    ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                    try {
                        // 商品 减库存 加销量 店家加销量
                        productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                item.getIsWalletPay(), tokenUser, item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), order.getUserId());
                    } catch (Exception e) {
                        log.error("程序出现异常：e:{}", GlobalExceptionHandler.getExceptionToString(e));
                        log.error("减库存发生异常 订单id :{}", item.getId());
                    }

                    switch (item.getActivityType()) {
                        case "RETURN_COUPON":
                            this.addReturnCoupon(item.getActivityMax(), RedisConstants.RETURN_COUPON + order.getH5Token());//记录用户返现红包金额
                            break;
                        case "WALLET_DEDUCT":
                            subH5Wallet(item.getActivityMax(), order.getH5Token());
                            break;
                        case "GET_SCORE":
                            addH5Wallet(item.getActivityMax(), order.getH5Token());
                            break;
                        case "LIVING_CENTER":
                            try {
                                activityType.set(1);
                            } catch (Exception e) {
                            }
                            break;
                        case "SHOPPING_CARNIVAL":
                            if (item.getActivityMax() != null) {
                                addH5Score(item.getActivityMax().intValue(), order.getH5Token());
                            }
                            break;
                        case "CASH_COUPON":
                            this.addUsedActivityMax(item.getActivityMax(), RedisConstants.RETURN_COUPON + order.getH5Token());//记录用户使用红包金额
                            updateCouponRecord(order.getH5Token(), item.getProductId());
                            break;
                        case "MEMBER_SUBSIDY":
                        case "OLD_FOR_NEW":
                            String key = RedisConstants.SUBSIDYKEY + order.getH5Token();
                            log.info("===adapay 微信小程序支付回调，获取当前platformData={}=,orderSource={}==", TokenUtil.getPlatformData(), orders.getOrderSource());
                            String subsidyObj = "";
                            try {
                                subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                            } catch (Exception e) {
                                log.info("===redis get key is err===");
                            }
//                                if ("APP".equals(TokenUtil.getPlatformData().toUpperCase())) {
                            this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, order.getH5Token(), orders.getUserId());
//                                } else {
                            if (StringUtils.isNotEmpty(subsidyObj)) {
                                redisService.delete(key, item.getProductId().toString());
                            }
                            this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, order.getH5Token());
//                                }
                            break;
                    }

                });
                // 发送短信
                try {
                    sendOrderPaySucSms(order, ordersInfoList.get(0), ordersInfoList.size());
                    if (1 == activityType.get() && order.getRealTotalMoney().compareTo(new BigDecimal(50)) > 0) {
                        addH5Wallet(order.getRealTotalMoney(), order.getH5Token());
                    }
                } catch (Exception e) {

                }
                List<Orders> ordersList = ordersMapper.selectByExample(example);
                if (!CollectionUtils.isEmpty(ordersList)) {
                    try {
                        subStock(ordersList.get(0).getId());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (orderPushSwitch) {
                        try {
                            log.info("上传供应链9============{}", ordersList.get(0).getId());
                            ordersUpload(ordersList.get(0).getId(),null);
                        } catch (Exception e) {
                            log.error("上传供应链9失败============{}", e);
                        }
                    }
                }
            } else {
                // 失败，更新支付订单信息
                pay.setIsSubscribe("");
                pay.setTradeType("adapay");
                Map<String,String> expend =(Map) map.get("expend");
                pay.setBankType(expend.get("bank_type"));
                pay.setTotalFee(new BigDecimal(map.get("pay_amt").toString()).multiply(new BigDecimal(100)).intValue());
                pay.setResText(JSONObject.toJSONString(map));
                pay.setPayTime(DateTimeUtil.dealDateFormat(map.get("created_time").toString()));
                pay.setPayType(com.ytjj.common.enums.PayPayTypeEnums.FAIL.getType());
                pay.setUpdateTime(new Date());
                ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
            }
        }
        return resCode;
    }

    private int updateOrderPay(WxPayOrderNotifyV3Result.DecryptNotifyResult notifyResult) {
        int orderid = 0;
        log.info("微信支付处理订单请求数据：{}", JSONObject.toJSONString(notifyResult));
        // 查询订单是否是处理中
        String resOrderNo = notifyResult.getOutTradeNo();
        OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(resOrderNo);
        if (null == pay || (pay.getPayType().byteValue() != com.ytjj.common.enums.PayPayTypeEnums.BEING_PROCESSED.getType() && com.ytjj.common.enums.PayPayTypeEnums.FAIL.getType() != pay.getPayType().byteValue())) {
            return orderid;
        }

        if (notifyResult.getTradeState().equals("SUCCESS")) {
            // 更新支付订单信息
            pay.setIsSubscribe("");
            pay.setTradeType(notifyResult.getTradeType());
            pay.setBankType(notifyResult.getBankType());
            pay.setTotalFee(notifyResult.getAmount().getTotal());
            pay.setResText(JSONObject.toJSONString(notifyResult));
            pay.setPayTime(notifyResult.getSuccessTime());
            pay.setPayType(com.ytjj.common.enums.PayPayTypeEnums.SUCCEED.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
            // 更新订单信息
            Orders orders = new Orders();
            orders.setPayType(com.ytjj.common.enums.OrderPayTypeEnums.online_pay.name());
            orders.setPaySource(OrderPaySource.wx.name());
            orders.setIsPay(IsPayConstant.YES);
            orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
            orders.setPayTime(new Date());
            orders.setTradeNo(pay.getResOrderNo());
            OrdersExample example = new OrdersExample();
            example.createCriteria()
                    .andOrderNoEqualTo(pay.getOrderNo());
            ordersMapper.updateByExampleSelective(orders, example);


            // 获取订单信息
            Orders order = ordersDao.queryOrdersByOrderNo(pay.getOrderNo());
            orders.setUserId(order.getUserId());
            log.info("===order info==={}", order);
            orderid = order.getId();
            try {
                BigDecimal money = usersClient.getMoney(order.getUserId());
                log.info("===用户账户余额==={}, {}", money, order.getDeductionMoney());
                if (order.getDeductionMoney() != null && order.getDeductionMoney().compareTo(null == money ? BigDecimal.ZERO : money) > 0) {
                    log.error("===账户余额不足，支付失败==={}", order.getOrderNo());

                    OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
                    ordersInfoExample.createCriteria().andOrderIdEqualTo(order.getId());
                    List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
                    ordersInfoList.stream()
                            .forEach(item -> {
                                OrdersInfo ordersInfo = new OrdersInfo();
                                ordersInfo.setId(item.getId());
                                ordersInfo.setOrderinfoStatus(OrderStatusEnums.LOSE_EFFICACY.getValue());
                                ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                            });
                    orders.setOrderStatus(OrderStatusEnums.LOSE_EFFICACY.getValue());
                    orders.setSmallNote("订单已支付，但是余额不足！");
                    ordersMapper.updateOrderStatus(order.getId(), Integer.parseInt(OrderStatusEnums.LOSE_EFFICACY.getValue()));
                    return orderid;
                }
            } catch (Exception e) {
                log.error("===微信回调校验用户余额异常==={}", e);
            }

            log.info("===金额抵扣余额===");
            if (order.getDeductionMoney() != null && order.getDeductionMoney().doubleValue() > 0d) {
                log.info("===金额抵扣余额开始===");
                UserBalanceDto userBalanceDto = new UserBalanceDto();
                userBalanceDto.setUserId(orders.getUserId());
                userBalanceDto.setUpdateMoney(order.getDeductionMoney());
                userBalanceDto.setType("SUB");
                userBalanceDto.setSource(com.ytjj.common.enums.UserBalanceSourceEnums.DEDUCTION.name());
                userBalanceDto.setAmountType(1);
                userBalanceDto.setCode(orders.getOrderNo());
                usersClient.updateMoney(userBalanceDto);
            }

            log.info("===金额抵扣余额结束===");

            // 获取订单明细
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(order.getId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            ordersInfoList.stream()
                    .forEach(item -> {
                        // 修改订单详情状态
                        OrdersInfo ordersInfo = new OrdersInfo();
                        ordersInfo.setId(item.getId());
                        ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                        ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                        try {
                            // 商品 减库存 加销量 店家加销量
                            SellAfterDto sellAfterDto = new SellAfterDto(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(), item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), order.getUserId());
                            rabbitTemplate.convertAndSend(QueueConstants.SELL_AFTER_QUEUE_ONE, sellAfterDto);
                        } catch (Exception e) {
                            log.error(GlobalExceptionHandler.getExceptionToString(e));
                            log.error("减库存发生异常 订单id :{}", item.getId());
                        }

                        // 删除补贴价格
                        if ("OLD_FOR_NEW".equals(item.getActivityType())) {
                            String key = com.ytjj.common.constants.RedisConstants.SUBSIDYKEY_APP + order.getH5Token();
//                            if ("APP".equals(TokenUtil.getPlatformData().toUpperCase())) {
                            this.addUserdSubsidy(item, com.ytjj.common.constants.RedisConstants.RECORD_SUBSIDYKEY_APP, order.getH5Token(), order.getUserId());
//                            } else {
                            String subsidyObj = "";
                            try {
                                subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                            } catch (Exception e) {
                                log.info("===get redis value is err===");
                            }
                            if (StringUtils.isNotEmpty(subsidyObj)) {
                                redisService.delete(key, item.getProductId().toString());
                                this.addUserdSubsidy(item, com.ytjj.common.constants.RedisConstants.RECORD_SUBSIDYKEY_APP, order.getH5Token());
                            }
//                            }

                        }
                        // 扣除用户的红包余额
                        if ("CASH_COUPON".equals(item.getActivityType())) {
                            this.addUsedActivityMax(item.getActivityMax(), com.ytjj.common.constants.RedisConstants.RETURN_COUPON_APP + order.getH5Token());//记录用户使用红包金额
                        }
                        if ("RETURN_COUPON".equals(item.getActivityType())) {
                            this.addReturnCoupon(item.getActivityMax(), com.ytjj.common.constants.RedisConstants.RETURN_COUPON_APP + order.getH5Token());//记录用户返现红包金额
                        }

                    });
            sendOrderPaySucSms(order, ordersInfoList.get(0), ordersInfoList.size());
        } else {
            // 更新支付订单信息
            pay.setIsSubscribe("");
            pay.setTradeType(notifyResult.getTradeType());
            pay.setBankType(notifyResult.getBankType());
            pay.setTotalFee(notifyResult.getAmount().getTotal());
            pay.setResText(JSONObject.toJSONString(notifyResult));
            pay.setPayTime(notifyResult.getSuccessTime());
            pay.setPayType(com.ytjj.common.enums.PayPayTypeEnums.FAIL.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
        }
        log.info("处理订单完毕-");
        return orderid;
    }

    private void sendOrderPaySucSms(Orders orders, OrdersInfo ordersInfo, int size) {
        // 发送短信
        try {
            log.info("===cmpp下单成功发送短信手机号==={}", orders.getUserPhone());
            SmsDto smsDto = new SmsDto();
            smsDto.setPhone(orders.getUserPhone());
            smsDto.setType(2);
            String productName = ordersInfo.getProductName();
            if (size > 1) {
                if (productName.length() > 12) {
                    productName = productName.substring(0, 12) + "-";
                } else {
                    productName = productName + "-";
                }
            } else {
                if (productName.length() > 12) {
                    productName = productName.substring(0, 12) + "-";
                }
            }
            smsDto.setCode(productName);
            smsDto.setOrderSource(orders.getOrderSource());
            smsDto.setChannel(orders.getChannel());
            smsDto.setDomainUrl(orders.getDomainUrl());
            smsDto.setOrderId(orders.getId());
            smsDto.setToken(orders.getH5Token());
            rabbitTemplate.convertAndSend(QueueConstants.SMS_QUEUE, smsDto);

        } catch (Exception e) {
            log.error("下单成功发送短信失败,{}",e);
        }
    }

    private void updateH5OrderPay(WxPayOrderNotifyV3Result.DecryptNotifyResult notifyResult) {
        log.info("微信支付处理订单请求数据：{}", JSONObject.toJSONString(notifyResult));
        // 查询订单是否是处理中
        String resOrderNo = notifyResult.getOutTradeNo();
        OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(resOrderNo);
        if (null == pay || (!pay.getPayType().equals(PayPayTypeEnums.BEING_PROCESSED.getType()) && PayPayTypeEnums.FAIL.getType() != pay.getPayType().byteValue())) {
            return;
        }
        if (notifyResult.getTradeState().equals("SUCCESS")) {
            // 更新支付订单信息
            pay.setIsSubscribe("");
            pay.setTradeType(notifyResult.getTradeType());
            pay.setBankType(notifyResult.getBankType());
            pay.setTotalFee(notifyResult.getAmount().getTotal());
            pay.setResText(JSONObject.toJSONString(notifyResult));
            pay.setPayTime(notifyResult.getSuccessTime());
            pay.setPayType(PayPayTypeEnums.SUCCEED.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
            // 更新订单信息
            Orders orders = new Orders();
            orders.setPayType(OrderPayTypeEnums.online_pay.name());
            orders.setPaySource(OrderPaySource.wx.name());
            orders.setIsPay(IsPayConstant.YES);
            orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
            orders.setPayTime(new Date());
            orders.setTradeNo(pay.getResOrderNo());
            OrdersExample example = new OrdersExample();
            example.createCriteria()
                    .andOrderNoEqualTo(pay.getOrderNo());
            ordersMapper.updateByExampleSelective(orders, example);

            // 获取订单信息
            Orders order = ordersDao.queryOrdersByOrderNo(pay.getOrderNo());
            // 获取订单明细
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria()
                    .andOrderIdEqualTo(order.getId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            AtomicInteger activityType = new AtomicInteger(0);
            ordersInfoList.stream()
                    .forEach(item -> {
                        String tokenUser = redisService.get(order.getH5Token());

                        // 修改订单详情状态
                        OrdersInfo ordersInfo = new OrdersInfo();
                        ordersInfo.setId(item.getId());
                        ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                        ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                        try {
                            // 商品 减库存 加销量 店家加销量
                            productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                    item.getIsWalletPay(), tokenUser, item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), order.getUserId());
                        } catch (Exception e) {
                            log.error("程序出现异常：e:{}", GlobalExceptionHandler.getExceptionToString(e));
                            log.error("减库存发生异常 订单id :{}", item.getId());
                        }

                        switch (item.getActivityType()) {
                            case "RETURN_COUPON":
                                this.addReturnCoupon(item.getActivityMax(), RedisConstants.RETURN_COUPON + order.getH5Token());//记录用户返现红包金额
                                break;
                            case "WALLET_DEDUCT":
                                subH5Wallet(item.getActivityMax(), order.getH5Token());
                                break;
                            case "GET_SCORE":
                                addH5Wallet(item.getActivityMax(), order.getH5Token());
                                break;
                            case "LIVING_CENTER":
                                try {
                                    activityType.set(1);
                                } catch (Exception e) {
                                }
                                break;
                            case "SHOPPING_CARNIVAL":
                                if (item.getActivityMax() != null) {
                                    addH5Score(item.getActivityMax().intValue(), order.getH5Token());
                                }
                                break;
                            case "CASH_COUPON":
                                this.addUsedActivityMax(item.getActivityMax(), RedisConstants.RETURN_COUPON + order.getH5Token());//记录用户使用红包金额
                                updateCouponRecord(order.getH5Token(), item.getProductId());
                                break;
                            case "MEMBER_SUBSIDY":
                            case "OLD_FOR_NEW":
                                String key = RedisConstants.SUBSIDYKEY + order.getH5Token();
                                log.info("===微信支付回调，获取当前platformData={}=,orderSource={}==", TokenUtil.getPlatformData(), orders.getOrderSource());
                                String subsidyObj = "";
                                try {
                                    subsidyObj = redisService.getMapString(key, item.getProductId().toString());
                                } catch (Exception e) {
                                    log.info("===redis get key is err===");
                                }
//                                if ("APP".equals(TokenUtil.getPlatformData().toUpperCase())) {
                                this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, order.getH5Token(), orders.getUserId());
//                                } else {
                                if (StringUtils.isNotEmpty(subsidyObj)) {
                                    redisService.delete(key, item.getProductId().toString());
                                }
                                this.addUserdSubsidy(item, RedisConstants.RECORD_SUBSIDYKEY, order.getH5Token());
//                                }
                                break;
                        }

                    });
            // 发送短信
            try {
                //  AliyunSmsUtil.sendSms(telephone,1,"");
                sendOrderPaySucSms(order, ordersInfoList.get(0), ordersInfoList.size());
                if (1 == activityType.get() && order.getRealTotalMoney().compareTo(new BigDecimal(50)) > 0) {
                    addH5Wallet(order.getRealTotalMoney(), order.getH5Token());
                }
            } catch (Exception e) {
            }

            List<Orders> ordersList = ordersMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(ordersList)) {
                try {
                    subStock(ordersList.get(0).getId());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (orderPushSwitch) {
                    try {
                        log.info("上传供应链9============{}", ordersList.get(0).getId());
                        ordersUpload(ordersList.get(0).getId(),null);
                    } catch (Exception e) {
                        log.error("上传供应链9失败============{}", e);
                    }
                }
            }

            //推送百度事件信息
            try{
                String h5Token = order.getH5Token();
                new Thread(()->{
                    String usesInfo = redisService.get(h5Token);
                    String a_oId = "";
                    if (StringUtils.isNotBlank(usesInfo)) {
                        UsersResponse usersResponse = com.alibaba.fastjson.JSONObject.parseObject(usesInfo, UsersResponse.class);
                        if (StringUtils.isNotBlank(usersResponse.getAoId())) {
                            a_oId =  usersResponse.getAoId();
                        }
                    }
                    if(StringUtils.isNotBlank(a_oId)){
                        List<ConversionType> conversionTypes = new ArrayList<>();
                        // 编辑一条转化数据
                        ConversionType cv = new ConversionType();
                        cv.setLogidUrl(a_oId); // 设置落地页url
                        cv.setNewType(90); // 设置转化类型
                        cv.setConvertTime(System.currentTimeMillis() / 1000);
                        conversionTypes.add(cv);
                        BaiduApiUtil.sendConvertData(baiduToken, conversionTypes);
                    }
                }).start();
            }catch (Exception e) {
                log.error("推送到百度事件信息错误:{}",e.getMessage());
            }

            //用户支付订单数据预警
            try{
                //测试排除
                if (!order.getTel().equals("17388585858") && !order.getUserName().contains("测试")){
                    Integer orderNum = ordersMapper.queryUserPaySuccessOrderNum(order.getTel(), 1);
                    if (orderNum>=checkOrderNum) {
                        FeiShuUtil.sendOrderNumMsg(PlatformEnum.getPlatformName(ordersInfoList.get(0).getChildOrderNo().substring(0,1))
                                +"       "+order.getTel()+order.getUserName()+"已支付"+ orderNum +"笔 请检查!");
                    }
                }
            }catch (Exception e) {
                log.error("查询用户支付订单数据预警失败:{}",e.getMessage());
            }

        } else {
            // 更新支付订单信息
            pay.setIsSubscribe("");
            pay.setTradeType(notifyResult.getTradeType());
            pay.setBankType(notifyResult.getBankType());
            pay.setTotalFee(notifyResult.getAmount().getTotal());
            pay.setResText(JSONObject.toJSONString(notifyResult));
            pay.setPayTime(notifyResult.getSuccessTime());
            pay.setPayType(com.ytjj.common.enums.PayPayTypeEnums.FAIL.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
        }

    }

    /**
     * adapay H5 更新订单支付信息
     */
    private void updateAdapayH5OrderPay(Map<String,String> map) {


    }

    public static final String TYPE = "H5";
    public static final String TRADE_TYPE = "JSAPI";

    /**
     * 申请交易账单API
     *
     * @throws WxPayException
     */
    @Override
    public String tradebillByWx() throws WxPayException {
        LocalDate ld = LocalDate.now(ZoneId.systemDefault());
        ld = ld.plusDays(-1);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String dateStr = ld.format(fmt);

        PayConfig payConfig = ordersDao.getPayConfigByCompany(COMPANY, TYPE, TRADE_TYPE);

        WxPayService wxPayService = WxPayServiceUtil.getWxPayService(payConfig);
        wxPayService.getConfig().setTradeType(WxPayConstants.TradeType.JSAPI);
        wxPayService.getConfig().setPrivateKeyPath(payConfig.getPrivateKeyPath());
        wxPayService.getConfig().setCertSerialNo(payConfig.getCertSerialNo());
        wxPayService.getConfig().setApiV3Key(payConfig.getWxKey());

        JSONObject returnJson = WxpayV3Util.tradebill(dateStr, wxPayService.getConfig());
        log.info("===tradebillByWx==={}", returnJson);
        return returnJson.toJSONString();
    }

    @Override
    public void downloadBill(HttpServletResponse servletResponse) throws Exception {
        PayConfig payConfig = ordersDao.getPayConfigByCompany(COMPANY, TYPE, TRADE_TYPE);

        WxPayService wxPayService = WxPayServiceUtil.getWxPayService(payConfig);
        wxPayService.getConfig().setTradeType(WxPayConstants.TradeType.JSAPI);
        wxPayService.getConfig().setPrivateKeyPath(payConfig.getPrivateKeyPath());
        wxPayService.getConfig().setCertSerialNo(payConfig.getCertSerialNo());
        wxPayService.getConfig().setApiV3Key(payConfig.getWxKey());

        LocalDate ld = LocalDate.now(ZoneId.systemDefault());
        ld = ld.plusDays(-1);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String dateStr = ld.format(fmt);
        JSONObject billUrlJson = WxpayV3Util.tradebill(dateStr, wxPayService.getConfig());

        InputStream inputStream = WxpayV3Util.downloadBill(billUrlJson.toJSONString(), wxPayService.getConfig(), servletResponse);

//        File file = new File("/mnt/tradebill/" + dateStr + ".zip");
        File file = new File("/mnt/tradebill/" + dateStr);

        OutputStream os = null;
        try {
            os = new FileOutputStream(file);
            int len = 0;
            byte[] buffer = new byte[8192];

            while ((len = inputStream.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        } finally {
            os.flush();
            os.close();
            inputStream.close();
        }
    }

    /**
     * 支付成功扣库存
     * @param orderId
     */
    @Override
    public void subStock(Integer orderId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        if (orders.getIsPay() != 1) {
            return;
        }
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(orderId);
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
        ordersInfoList.stream().forEach(ordersInfo -> {
            Product product = productMapper.selectByPrimaryKey(ordersInfo.getProductId());
            try {
                //扣减或退还库存
                log.info("========扣减库存=========");
                subAndAddStock(ordersInfo.getChildOrderNo(), 1, product.getIsZeroProduct(), "sub");
            } catch (Exception e) {
                log.error("========扣减库存========orders.getOrderNo()====={}", ordersInfo.getChildOrderNo());
            }
        });
    }

    @Override
    public Integer sumOrderVolumeByActivityType(String activityType) {
        String redisKey = "product:order:volume:activityType:" + activityType;
        String volumeVal = redisService.get(redisKey);
        if (!StringUtils.isEmpty(volumeVal)) {
            return Integer.parseInt(volumeVal);
        }
        Integer volume = ordersMapper.sumOrderVolumeByActivityType(activityType);
        redisService.set(redisKey, String.valueOf(volume));
        redisService.expire(redisKey, 60 * 60);
        return volume;
    }
    /**
     * 微信退款回调
     */
    @Override
    public String wxV3RefundBack(String type, String data, SignatureHeader signatureHeader) throws WxPayException {
        String paytype = "";
        String tradeType = "";
        String company="";
        if (WxPayConstant.ISV_TRADE_TYPE_H5.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "MWEB";
            company=WxPayConstant.COMPANY;
        }else if (WxPayConstant.ISV_TRADE_TYPE_JSAPI.equalsIgnoreCase(type)) {
            paytype = "APP";
            tradeType = "JSAPI";
            company=WxPayConstant.COMPANY;
        } else if (WxPayConstant.ISV_PHONE_CHARGES.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "PHONE_CHARGES";
            company=WxPayConstant.COMPANY;
        } else if (WxPayConstant.ISV_TRADE_TYPE_H5_TXG.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "MWEB";
            company=WxPayConstant.COMPANY_TXG;
        } else if (WxPayConstant.ISV_TRADE_TYPE_APP_TXG.equalsIgnoreCase(type)) {
            paytype = "APP";
            tradeType = "APP";
            company=WxPayConstant.COMPANY_TXG;
        } else if (WxPayConstant.ISV_TRADE_TYPE_JSAPI_TXG.equalsIgnoreCase(type)) {
            paytype = "APP";
            tradeType = "JSAPI";
            company=WxPayConstant.COMPANY_TXG;
        }
        else if (WxPayConstant.TRADE_TYPE_H5_JSAPI.equalsIgnoreCase(type)) {
            paytype = "H5";
            tradeType = "JSAPI";
            company=WxPayConstant.NEW_COMPANY;
        }
        PayConfig payConfig = ordersDao.getPayConfigByCompany(company, paytype, tradeType);
        WxPayService wxPayService = WxPayServiceUtil.getWxPayService(payConfig);
        wxPayService.getConfig().setPrivateKeyPath(payConfig.getPrivateKeyPath());
        wxPayService.getConfig().setCertSerialNo(payConfig.getCertSerialNo());
        wxPayService.getConfig().setApiV3Key(payConfig.getWxKey());
        wxPayService.getConfig().setPrivateCertPath(payConfig.getPrivateCertPath());
        WxPayRefundNotifyV3Result notifyResult = wxPayService.parseRefundNotifyV3Result(data, signatureHeader);

        log.info("====notifyResult:{}", JSONObject.toJSONString(notifyResult));
        String refundStatus = notifyResult.getResult().getRefundStatus();
        WxPayRefundNotifyV3Result.DecryptNotifyResult decryptRefundNotifyResult = notifyResult.getResult();
        if ("SUCCESS".equalsIgnoreCase(refundStatus)) {
            handleV3Refund(decryptRefundNotifyResult);
            return WxPayNotifyResponse.success("成功");
        } else {
            handleV3Refund(decryptRefundNotifyResult);
            return WxPayNotifyResponse.fail("失败");
        }
    }

    public void handleV3Refund(WxPayRefundNotifyV3Result.DecryptNotifyResult decryptRefundNotifyResult) {
        //退款状态
        String refundStatus = decryptRefundNotifyResult.getRefundStatus();
        //退款单号
        String outRefundNo =decryptRefundNotifyResult.getOutRefundNo();
        OrdersRefundExample ordersRefundExample = new OrdersRefundExample();
        ordersRefundExample.createCriteria()
                .andRefundNoEqualTo(outRefundNo);
        List<OrdersRefund> ordersRefundList = refundMapper.selectByExample(ordersRefundExample);

        if (null == ordersRefundList && ordersRefundList.size() <= 0) {
            log.info("微信退款(handleV3Refund)，没有找到该订单号：{}", outRefundNo);
            return;
        }
        if ("SUCCESS".equals(refundStatus)) {
            log.info("微信退款(handleV3Refund),退款单单号：{}", outRefundNo);
            // 成功
            // 将订单状态改成已退款
            OrdersRefund ordersRefund = ordersRefundList.get(0);
            // 将退款订单改成退款成功，并且记录
            if (ordersRefund.getStatus().intValue() == 2) {
                return;
            }
            ordersRefund.setStatus(2);
            ordersRefund.setResText(JSONObject.toJSONString(decryptRefundNotifyResult));
            ordersRefund.setUpdateTime(new Date());
            refundMapper.updateByPrimaryKeySelective(ordersRefund);

            Orders orders = new Orders();
            orders.setOrderStatus("6");
            orders.setIsRefund(1);
            orders.setRefundNo(outRefundNo);

            OrdersExample example = new OrdersExample();
            example.createCriteria()
                    .andOrderNoEqualTo(ordersRefund.getOrderNo());
            ordersMapper.updateByExampleSelective(orders, example);
            Orders orders1 = ordersDao.queryOrdersByOrderNo(ordersRefund.getOrderNo());
            if (orders1 != null) {
                ordersDao.updateStatusByOrderId("6", orders1.getId());
            }
            // 同步原路返回页退款时间
            refundMapper.updateRefundTime(ordersRefund.getOrderNo());

        } else {
            log.info("====handleV3Refund.fail:outRefundNo={}", outRefundNo);
            OrdersRefund ordersRefund = ordersRefundList.get(0);
            // 失败
            ordersRefund.setStatus(3);
            ordersRefund.setResText(JSONObject.toJSONString(decryptRefundNotifyResult));
            ordersRefund.setUpdateTime(new Date());
            refundMapper.updateByPrimaryKeySelective(ordersRefund);
        }
    }

    /**
     * 获取某一天的最后一毫秒的日期值
     */
    public static Date getEndOfDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    @Override
    public CommonResult checkWxMiniPayStatus(Integer orderId) {
        if(null == orderId){
            return CommonResult.failed("参数有误！");
        }
        String s = redisService.get(RedisConstants.ORDER_PAY_INFO + orderId);
        if(StringUtils.isEmpty(s)){
            return CommonResult.failed("订单不存在或未支付！");
        }else {
            redisService.delete(RedisConstants.ORDER_PAY_INFO + orderId);
            return CommonResult.success(s);
        }
    }

    @Override
    public Integer queryNoPayAndNoCancelCount(String h5Token) {
        return ordersMapper.queryNoPayAndNoCancelCount(h5Token);
    }

    @Override
    public void updateOrderAddress(String childOrderNo, String tel, String address,String newTel,String userName) {
        OrdersInfo ordersInfo = ordersInfoMapper.queryByChildOrderNo(childOrderNo);
        if (ordersInfo!=null && "1".equals(ordersInfo.getOrderinfoStatus())){
            //供应商未导出发货的才能修改地址
            Map<String, String> map = Maps.newHashMap();
            map.put("childOrderNo", childOrderNo);
            String result = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/order/findBankOrdreByChildOrderNo", map, supplyApiConfig.getHeadsMap());
            if (result!=null && result.equals("1")){
                ordersDao.updateOrderAddress(ordersInfo.getOrderId(),tel,address,newTel,userName);

                Map<String, String> map2 = Maps.newHashMap();
                map2.put("childOrderNo", childOrderNo);
                map2.put("tel", tel);
                map2.put("address", address);
                map2.put("newTel", newTel);
                map2.put("userName", userName);

                String result2 = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/order/updateBankerOrderAddress", map2, supplyApiConfig.getHeadsMap());
                if (result2!=null && result2.equals("ok")){
                    log.info("{},修改地址成功",childOrderNo);
                }
            }else {
                throw new ApiException("订单已发货无法修改 请联系在线客服处理!");
            }
        }else{
            throw new ApiException("订单已发货无法修改 请联系在线客服处理!");
        }
    }
}
